我有一个带有标签的自定义控件。此控件具有如下属性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 {}块...
答案 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
被调用并将文本传递给您的实际标签!