我想使用类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
答案 0 :(得分:1)
当您通过绑定设置它们时,依赖属性不会以这种方式工作。 <{1}} 被调用。 Binding正在调用(实质上):
DependencyObject.SetCurrentValue
所以,是的,SetCurrentValue vs SetValue。 yourObject.SetCurrentValue(YourClassName.RangeSliderModelProperty, someValue);
将覆盖依赖项属性的任何绑定; SetValue
赢了。 IIRC这与XAML中的样式触发器不能覆盖属性设置的值的方式有关。幸运的是,这与你在这里所做的事情没有直接关系。
最重要的是,您的SetCurrentValue
处理程序是您放置值更改时需要调用的代码的位置。依赖项属性和常规.NET CLR属性是两个独立的机制。
如果我完全省略了公共属性,我已经在XAML中正确绑定了依赖项属性;我刚刚测试了一下,发现我的测试示例就是这种情况。在评论中你提到你没有发现你的代码就是这种情况,所以显然我需要做更多的阅读。
如果您需要让子类响应更改,您可以编写一个他们可以覆盖的虚拟方法,并在ModelPropertyChanged
中调用它,或者写一个ModelPropertyChanged
事件并在{{ModelChanged
中引发它1}}。
他们可以通过ModelPropertyChanged
添加ValueChanged
处理程序,但它正好与你陌生,以免他们在谷歌搜索如何做到这一点,通过编写虚拟方法或事件。