【问题标题】:c# - How to set default values of custom controls for wpf designer?c# - 如何为 wpf 设计器设置自定义控件的默认值?
【发布时间】:2011-08-17 00:45:20
【问题描述】:

如何为我的自定义 wpf 组件设置默认值? 我有一个属性为“public Protection Protection{set;get;}”的文本字段。保护是一个枚举:

public class Field3270Attributes{
    public enum Protection
    {
        PROTECTED,
        UNPROTECTED,
        AUTOSKIP
    }
}

默认值应该是 autoskip 但 protected 在 wpf 设计器中列为默认值,因为它是枚举中的第一个元素。 在 Textfield 构造函数中设置保护没有帮助。 我试过 DependencyProperty 确实有效,但如果我想要除默认值以外的任何值都可以工作,我必须指定一个回调(setProtection)。 如果我不指定回调,则在 wpf 设计器中更改值无效。 有没有办法在不必为每个属性指定回调方法的情况下获得相同的行为?

public class Textfield{

    public static readonly DependencyProperty ProtectionProperty =
            DependencyProperty.Register("Protection",
                                        typeof(Field3270Attributes.Protection),
                                        typeof(Textfield3270),
                                        new FrameworkPropertyMetadata(Field3270Attributes.Protection.PROTECTED, setProtection));

    private static void setProtection(object sender, DependencyPropertyChangedEventArgs e)
    {
        Textfield field = (Textfield)sender;
        field.Protection = (Field3270Attributes.Protection)e.NewValue;
    }

    private Field3270Attributes.Protection protection;

    public Field3270Attributes.Protection Protection
    {
        get
        {
            return protection;
        }

        set
        {
            this.protection = value;

            if (value == Field3270Attributes.Protection.UNPROTECTED)
            {
                this.IsReadOnly = false;
                Background = Brushes.White;
            }
            else
            {
                this.IsReadOnly = true;
                Background = Brushes.LightSteelBlue;
            }
        }
    }

    public Textfield3270()
    {

        this.Protection = Field3270Attributes.Protection.PROTECTED;
    }

}

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    您的DependencyProperty 定义定义了默认值。将FrameworkPropertyMetadata中的第一个参数从PROTECTED改为AUTOSKIP

    public static readonly DependencyProperty ProtectionProperty =
        DependencyProperty.Register("Protection",
            typeof(Field3270Attributes.Protection),
            typeof(Textfield3270),
            new FrameworkPropertyMetadata(Field3270Attributes.Protection.AUTOSKIP, setProtection));
    

    编辑

    您正在通过实现您自己的同名版本来覆盖您的Protection DependencyProperty。完全删除您对Protection {get; set;} 的定义。

    如果您希望它们显示在 XAML 设计器中,请将 Get/Set 定义为静态方法,如下所示:

    public static Field3270Attributes.Protection GetProtection(DependencyObject obj)
    {
        return (Field3270Attributes.Protection)obj.GetValue(ProtectionProperty);
    }
    
    public static void SetProtection(DependencyObject obj, Field3270Attributes.Protection value)
    {
        obj.SetValue(ProtectionProperty, value);
    }
    

    如果你想在 PropertyChanged 上附加一些逻辑,你可以在你的类构造函数中使用这个代码:

    DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(Textfield.ProtectionProperty, typeof(Textfield));
    if (dpd != null) dpd.AddValueChanged(this, delegate { Protection_Changed(); });
    

    您更改后的方法如下所示:

    private void Protection_Changed()
    {
        Field3270Attributes.Protection protection = GetProtection(this);
    
        // Do something with value
    }
    

    【讨论】:

    • 谢谢,但这只是我的描述中的一个错误。我之前在自动跳过时将其更改为受保护,但问题是,我如何设置默认值并确保从默认值更改为 wpf 设计器中的任何其他值都可以识别?如果没有回调,我可以更改值并且什么也不会发生,但我不想为每个值定义回调。
    • 注册 DependencyProperty 时,会自动为该属性创建 Get/Set。您似乎覆盖了指向 DependencyProperty 的默认 TextField.Protection,并实现了您自己的属性版本。尝试删除您的 Protection 属性版本,看看它是否有效。
    • 是的,我正在覆盖 Protection 属性的 get/set,如您在上面的代码中所见。我现在将其更改为自动实现的属性: public Field3270Attributes.Protection Protection { set;得到;但这也不起作用,我仍然需要回调,即使它只设置字段属性。
    • @Markus 查看我的编辑。 public Field3270Attributes.Protection Protection { set; get; } 仍在覆盖 DependencyProperty 保护。
    猜你喜欢
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多