【问题标题】:How to make a DependencyProperty properly coerce a value's type for a binding如何使 DependencyProperty 正确强制绑定值的类型
【发布时间】:2015-09-10 19:34:20
【问题描述】:

我有一个ItemsControl 子类,其行为类似于Selector,但它不能是Selector 的子类,因为所选项目不一定在Items 集合中。所以我被困在重新实现很多Selector 的东西。

我的班级有一个SelectedValuePath 属性。如果该属性有值,我将创建一个绑定,以便当SelectedItem 更改时,"SelectedItem." + SelectedValuePath 的值将分配给SelectedValue。这非常有效——只要消费者将我的SelectedValue 绑定到与SelectedItem 上的值属性相同类型的属性

问题出在这里:

但是,如果所选项目具有用作值属性的 int ID 属性,并且 SelectedValue 绑定到视图模型上的 Nullable<int> SelectedID 属性,则绑定无法在视图上设置该属性模型,除非SelectedItem 为空。

我注意到 WPF ComboBox 类没有这个问题,所以它必须是可解决的,而不需要消费者提供值转换器。我试过CoerceValueCallback,但这对我没有任何作用。它不知道目标类型。它没有关于接收值的绑定的信息。

ComboBox.SelectedValue 在做什么而我却没有?

我相当熟悉IValueConverter 以及在使用控件时如何将值转换器添加到 XAML 中的绑定中。我不需要这方面的帮助。我在问是否有人知道ComboBox.SelectedValue 上的任何绑定如何将int 转换为int?,而无需控件的使用者向绑定添加值转换器。

【问题讨论】:

    标签: c# wpf xaml binding


    【解决方案1】:

    正如我所预料的那样,问题出在我所预料的地方。没有类型转换问题。

    看来问题出在我的班级内部。我正在使用绑定更新SelectedValue

    Binding binding = new Binding("SelectedItem." + SelectedValuePath);
    binding.Mode = BindingMode.OneWay;
    binding.Source = this;
    BindingOperations.SetBinding(this, MenuComboBox.SelectedValueProperty, binding);
    

    这似乎干扰了消费者对SelectedValue 的双向绑定。

    我有一个派生自DependencyObjectBindingTarget 类。它公开了一个名为ValueDependencyProperty,并在Value 更改时触发一个事件。我已经写了它来将值转发到“只读”DependencyPropertySelectionBoxItem,其中设置器受到保护。因此,我没有像上面那样从"SelectedItem."+SelectedValuePathSelectedValue 作为目标创建绑定,而是使用私有BindingTarget 实例作为目标,并在其ValueChanged 处理程序中设置SelectedValue。消费者的绑定现在按预期工作。

    //  The type argument to BindingTarget is the type of the property. 
    _selectedValueBindingTarget = new BindingTarget<Object>();
    
    _selectedValueBindingTarget.ValueChanged += (s, e2) =>
    {
        SelectedValue = e2.NewValue;
    };
    
    Binding binding = new Binding("SelectedItem." + SelectedValuePath);
    binding.Mode = BindingMode.OneWay;
    binding.Source = this;
    BindingOperations.SetBinding(_selectedValueBindingTarget, 
        BindingTarget<Object>.ValueProperty, binding);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-14
      • 2021-07-10
      • 1970-01-01
      • 1970-01-01
      • 2010-10-05
      • 1970-01-01
      • 1970-01-01
      • 2020-06-16
      相关资源
      最近更新 更多