【问题标题】:IValueConverter and binding a DependencyObjectIValueConverter 和绑定一个 DependencyObject
【发布时间】:2019-10-21 19:50:59
【问题描述】:

我有一个ComboBox,我需要在SelectedItem 上做一个转换器。问题是 IValueConverter 需要绑定值,但也需要 Collection。配置了DependencyObject,但它给了我一个错误消息

“System.Windows.Data.Binding”类型的对象无法转换为“System.Collections.ObjectModel.ObservableCollection`1[MyClass]”类型。

这是我的IValueConverter

public class MyConverter : DependencyObject, IValueConverter
{
    public static readonly DependencyProperty FoldersProperty = 
        DependencyProperty.Register(nameof(MyCollection), typeof(ObservableCollection<MyClass>), typeof(MyClassModelToMyClassID), new FrameworkPropertyMetadata(new ObservableCollection<MyClass>()));
    public ObservableCollection<MyClass> MyCollection
    {
        get { return GetValue(FoldersProperty) as ObservableCollection<MyClass>; }
        set { SetValue(FoldersProperty, value); }
    }
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        //Amazing Convert code that uses MyCollection and Value
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        //Amazing ConvertBack code that uses MyCollection and Value
    }
}

我是这样称呼它的:

<Page.Resources>
    <converter:MyConverter x:Key="Converter" MyCollection="{Binding DataCollection}" />
</Page.Resources>
....
<ComboBox 
    ItemsSource="{Binding DataCollection}"
    SelectedItem="{Binding Path=MyValue, Converter={StaticResource TaxCodeConverter}}" />

编辑:添加完整的 IValueConvert 减去 Convert 和 ConvertBack 代码

【问题讨论】:

    标签: wpf data-binding ivalueconverter


    【解决方案1】:

    和 BindingProxy 一样,它必须是 a Freezable。此外,不要将新的可观察集合传递给您的元数据。这是一个引用类型,所以这个转换器的所有实例都将使用相同的实际集合实例进行初始化。

    如果您遇到其他问题,请告诉我,但我已经完成了此操作并且能够绑定到依赖项属性。

    许多人认为更好的方法是多绑定和多值转换器。我认为拥有具有描述性名称的强类型属性是有价值的。

    public class MyConverter : Freezable, IValueConverter
    {
        /* omitted: Convert() and ConvertBack() */
    
        public MyConverter()
        {
            //  Initialize here if you need to
            MyCollection = new ObservableCollection<MyClass>();
        }
    
        protected override Freezable CreateInstanceCore()
        {
            return new MyConverter();
        }
    
        public static readonly DependencyProperty MyCollectionProperty =
            DependencyProperty.Register(nameof(MyCollection), 
                typeof(ObservableCollection<MyClass>), typeof(MyConverter),
                new FrameworkPropertyMetadata(null));
    
        public ObservableCollection<MyClass> MyCollection
        {
            get { return GetValue(MyCollectionProperty) as ObservableCollection<MyClass>; }
            set { SetValue(MyCollectionProperty, value); }
        }
    }
    

    XAML 用法将与您在问题中的用法一样:绑定依赖属性,并且绑定将更新 MyConverter 实例的该属性,前提是您的 Page 的 DataContext 具有名为 DataCollection 的适当类型的属性.

    <Page.Resources>
        <converter:MyConverter x:Key="Converter" MyCollection="{Binding DataCollection}" />
    </Page.Resources>
    

    【讨论】:

    • 传递可观察集合的正确方法是什么?
    • 如果 DataCollection 是 Page 的 DataContext 的一个属性,那么您在使用示例中的方式应该可以工作。
    • 好吧,我觉得很蠢,Converter={StaticResource TaxCodeConverter}},不让我看到变量MyCollection。是的,DataCollection 是 Page 的 DataContext 的一个属性。
    猜你喜欢
    • 1970-01-01
    • 2011-11-18
    • 2011-06-14
    • 2022-01-09
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 2013-11-15
    相关资源
    最近更新 更多