【问题标题】:DependencyProperty on custom control not binding?自定义控件上的 DependencyProperty 未绑定?
【发布时间】:2014-08-07 19:21:51
【问题描述】:

我有一个带有标签的自定义控件。该控件有一个属性Label,如下所示:

public string Label
{
    get { return (string)GetValue(LabelProperty); }
    set
    {
        label.Text = value; 
        SetValue(LabelProperty, value);
    }
}

public static DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(SuperButton), new PropertyMetadata(null));

注意,带有小 l 的标签是一个内部文本块。 SuperButton 是控件的名称。

然后我有这个简单的对象:

class Student  : INotifyPropertyChanged
{
    public string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; OnPropertyChanged( new PropertyChangedEventArgs("Name")); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, e);
        }
    }
}

然后我用这个 XAML 绑定:

<UIFragments:SuperButton Margin="531,354,555,367" Label="{Binding Name}"></UIFragments:SuperButton>

然后我将它与按钮实例放在同一页面中

    Student s = new Student { Name = "John Smith" };
        DataContext = s;

我尝试将控件的数据上下文设置为自身,但没有任何效果。将标签设置为字符串有效。

如果我使用数据绑定,则永远不会触发 set{} 块...

【问题讨论】:

    标签: c# xaml windows-runtime winrt-xaml


    【解决方案1】:

    XAML 不会调用您的 Setter 方法,正如 at MSDN 所指出的那样:

    WPF XAML 处理器使用属性系统方法进行依赖 加载二进制 XAML 和处理属性时的属性 依赖属性。这有效地绕过了属性 包装纸。当你实现自定义依赖属性时,你必须 考虑到这种行为,并应避免将任何其他代码放入 您的属性包装器,而不是属性系统方法 GetValue 和 SetValue。

    你需要做的是注册一个回调方法,只要依赖属性发生变化就会触发:

    public static DependencyProperty LabelProperty = DependencyProperty.Register(
        "Label", 
        typeof(string), 
        typeof(SuperButton), 
        new PropertyMetadata(null, PropertyChangedCallback)
    );
    

    注意最后一行的PropertyChangedCallback!该方法实现如下:

    private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
    {
        SuperButton userControl = ((SuperButton)dependencyObject);
        userControl.label.Text = (string) args.NewValue;
    }
    

    现在可以将依赖属性的 getter 和 setter 简化为:

    public string Label
    {
        get { return (string)GetValue(LabelProperty); }
        set { SetValue(LabelProperty, value); }
    }
    

    现在每当 Label 属性发生变化时,例如通过在您的页面中绑定它,PropertyChangedCallback 被调用并将文本传递给您的实际标签!

    【讨论】:

    • 我已经尝试过了,但似乎只有当我将属性设置为字符串时才会调用回调 - 如果我绑定到它,则不会发生任何事情。有什么想法吗?
    • 检查 DependencyProperty 的默认值(new PropertyMetadata(...) 的第一个参数)和您要绑定的变量的 value - 如果两者相同,则回调获胜'不执行。
    • 非常感谢您的反馈!结果我的用户控件构造函数中的数据上下文设置为“this”。我的愚蠢错误!再次感谢
    猜你喜欢
    • 2011-08-06
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    相关资源
    最近更新 更多