DependencyProperty和DataBinding - 为什么在UserControl加载时不调用属性设置器?

时间:2016-06-28 17:20:44

标签: wpf dependency-properties

我想使用类RangeSliderRangeSliderModel的行为进行建模,该类具有描述给定值集的大小(宽度)的属性。

然后,我创建了一个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;
    }

我希望覆盖SetValueGetValue属性,但即使我将此DependencyProperty绑定到ViewModel中的相应Source,也永远不会调用setter!而且我不能完全理解为什么会调用PropertyChangedHandler,而不是我应该对这些信息做什么 - 我希望以类似于ValueConverter的方式使用GetValueSetValue

1 个答案:

答案 0 :(得分:1)

当您通过绑定设置它们时,依赖属性不会以这种方式工作。 <{1}} 调用。 Binding正在调用(实质上):

DependencyObject.SetCurrentValue

所以,是的,SetCurrentValue vs SetValueyourObject.SetCurrentValue(YourClassName.RangeSliderModelProperty, someValue); 将覆盖依赖项属性的任何绑定; SetValue赢了。 IIRC这与XAML中的样式触发器不能覆盖属性设置的值的方式有关。幸运的是,这与你在这里所做的事情没有直接关系。

最重要的是,您的SetCurrentValue处理程序是您放置值更改时需要调用的代码的位置。依赖项属性和常规.NET CLR属性是两个独立的机制。

如果我完全省略了公共属性,我已经在XAML中正确绑定了依赖项属性;我刚刚测试了一下,发现我的测试示例就是这种情况。在评论中你提到你没有发现你的代码就是这种情况,所以显然我需要做更多的阅读。

如果您需要让子类响应更改,您可以编写一个他们可以覆盖的虚拟方法,并在ModelPropertyChanged中调用它,或者写一个ModelPropertyChanged事件并在{{ModelChanged中引发它1}}。

他们可以通过ModelPropertyChanged 添加ValueChanged处理程序,但它正好与你陌生,以免他们在谷歌搜索如何做到这一点,通过编写虚拟方法或事件。