首页 文章

DependencyProperty和DataBinding - 为什么在UserControl加载时不调用属性setter? [重复]

提问于
浏览
0

这个问题在这里已有答案:

我想模拟 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;
    }

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

1 回答

  • 1

    通过绑定设置它们时,依赖项属性不起作用 . DependencyObject.SetCurrentValue 被调用 . Binding正在调用(实质上):

    yourObject.SetCurrentValue(YourClassName.RangeSliderModelProperty, someValue);
    

    所以,是的,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 处理程序,但是通过编写虚拟方法或事件,它可以帮助他们解决问题 .

相关问题