我想我在这里缺少一些非常基本的东西。
我创建了一个UserControl
DependencyProperty
,定义如下:
public static DependencyProperty SpinnerColourProperty = DependencyProperty.Register("SpinnerColour", typeof(Color), typeof(LoadingControl), new PropertyMetadata(Colors.Black));
public Color SpinnerColour
{
get
{
return (Color)GetValue(SpinnerColourProperty);
}
set
{
SetColour(value);
SetValue(SpinnerColourProperty, value);
}
}
(是的,我更喜欢英式英语......所以起诉我:P)
正如预期的那样,SetColour
方法会改变控件的外观。
如果在我的代码中我写customControl1.SpinnerColour = Colors.Red
,那么控件将正确地改变属性和通过setter应用的视觉效果的颜色。 (如果我在Visual Studio的设计师中使用该属性,我甚至可以观察到这种变化!)
但是,如果我将数据绑定应用于该属性然后更改它绑定的元素,则属性的值将会更改,但是将永远不会调用setter并且实际显示将永远不会更改。
例如,如果我定义一个按钮和我的控件:
<my:MyControl x:Name="myControl1" SpinnerColour="{Binding ElementName=button1, Path=Background.Color, Mode=TwoWay}" />
<Button Content="Button" Height="23" Name="button1" Click="button1_Click" />
Click
事件会改变按钮背景的颜色:
private void button1_Click(object sender, RoutedEventArgs e)
{
button1.Background = new SolidColorBrush(Colors.Red);
}
然后,如果我使用调试器检查SpinnerColour
属性,它将为红色。但是,正如我所写,从不调用setter,实际控件永远不会改变它的颜色。
我做错了什么?
答案 0 :(得分:2)
你滥用依赖属性
调用SetValue
的本机CLR属性仅在代码中设置属性时使用
绑定基础结构直接调用SetValue
(而不是使用反射),因此您的代码永远不会运行。
你永远不应该在DependencyProeprty包装器中放置除GetValue
和SetValue
之外的任何代码
相反,您需要在DependencyProperty注册中指定ValueChangedCallback
,作为PropertyMetadata
构造函数的第二个参数。