这个问题在这里已有答案:
我想模拟 RangeSlider
的行为,使用类 RangeSliderModel
,其属性描述给定值集的大小(宽度) .
然后,我创建了一个UserControl,其中一些矩形的位置和大小应该代表那些属性,以及 Thumb
的一些实例,其中 DragDelta
事件用于调整这些矩形的大小并启用 RangeSliderModel
的新值的计算 .
最后,此UserControl的 DependencyProperty
类型为 RangeSliderModel
:
public RangeSliderModel Model
{
get
{
return (RangeSliderModel)GetValue(RangeSliderModelProperty);
// or instead calculate a RangeSliderModel from children sizes.
}
set
{
// this IS NOT called when UserControl loads
SetValue(RangeSliderModelProperty, value);
// here I could take the value and calculate new sizes for the children.
}
}
public static readonly DependencyProperty RangeSliderModelProperty =
DependencyProperty.Register("RangeSliderModel",
typeof(RangeSliderModel),
typeof(MyUserControl),
new PropertyMetadata(ModelPropertyChanged));
private static void ModelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// this IS called when UserControl loads.
RangeSliderModel model = e.NewValue as RangeSliderModel;
}
我期望覆盖 SetValue
和 GetValue
属性,但即使我将此DependencyProperty绑定到ViewModel中的相应Source,也永远不会调用setter!我不太明白为什么会调用PropertyChangedHandler,而不是我应该对这些信息做什么 - 我期望以类似于ValueConverter的方式使用 GetValue
和 SetValue
.
1 回答
通过绑定设置它们时,依赖项属性不起作用 .
DependencyObject.SetCurrentValue
被调用 . Binding正在调用(实质上):所以,是的,SetCurrentValue vs SetValue .
SetValue
将覆盖依赖项属性的任何绑定;SetCurrentValue
赢了't. IIRC this has to do with the way Style Triggers in XAML can' t覆盖属性设置的值 . 幸运的是,它在这里做了 .最重要的是,您的
ModelPropertyChanged
处理程序是您放置值更改时需要调用的代码的位置 . 依赖项属性和常规.NET CLR属性是两个独立的机制 .如果我完全省略了公共属性,我已经在XAML中正确绑定了依赖项属性;我刚刚测试了一下,发现我的测试示例就是这种情况 . 在评论中你提到你没有发现你的代码就是这种情况,所以显然我需要做更多的阅读 .
如果您需要让子类响应更改,您可以编写一个他们可以覆盖的虚方法,并在
ModelPropertyChanged
中调用它,或者写一个ModelChanged
事件并在ModelPropertyChanged
中引发它 .他们可以通过
DependencyPropertyDescriptor
添加一个ValueChanged
处理程序,但是通过编写虚拟方法或事件,它可以帮助他们解决问题 .