自定义控件上的DependencyProperty不绑定?

时间:2014-08-07 10:45:40

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

我有一个带有标签的自定义控件。此控件具有如下属性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;

我已经尝试将控件的datacontext设置为自身,但没有任何工作。将Label设置为字符串有效。

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

1 个答案:

答案 0 :(得分:2)

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被调用并将文本传递给您的实际标签!