WPF ObjectDataProvider参数

时间:2018-10-29 16:40:26

标签: wpf objectdataprovider

我有一个ObjectDataProvider用于获取枚举成员的列表:

<ObjectDataProvider x:Key="GetEnumContents" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
    <ObjectDataProvider.MethodParameters>
         <x:Type TypeName="Data:Status"/>
    </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>

然后与之配合使用

<ComboBox SelectedItem="{Binding Status, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Source={StaticResource GetEnumContents}}" />

然后在同一个窗口中,我想有一个用于其他枚举的组合框。如何从ComboBox声明中传递枚举类型?

我已经看到类似问题的解决方案,例如:

Path="MethodParameters[0]"

但是这里我不想将参数绑定到任何东西,我只想在ComboBox声明中对其进行硬编码。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

ObjectDataProvider不支持这种功能,但是您可以通过巧妙地使用BindingIValueConverter滥用来“伪造”它。

首先,IValueConverter

class EnumConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Enum.GetValues((Type)parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

这是您的用法:

<Window
    x:Class="EnumTest.MainWindow"
    [...snip...]
    xmlns:local="clr-namespace:EnumTest"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Window.Resources>
        <local:EnumConverter x:Key="EnumConverter" />
    </Window.Resources>
    <StackPanel>
        <ComboBox ItemsSource="{Binding Converter={StaticResource EnumConverter}, ConverterParameter={x:Type local:MyEnum1}}" />
        <ComboBox ItemsSource="{Binding Converter={StaticResource EnumConverter}, ConverterParameter={x:Type local:MyEnum2}}" />
    </StackPanel>
</Window>

一些测试枚举:

enum MyEnum1
{
    Red,
    Green,
    Blue,
}

enum MyEnum2
{
    Cat,
    Dog,
    Fish,
    Bird,
}

这将产生以下输出: enter image description here enter image description here

这利用了您可以将额外的参数传递给IValueConverter的事实,我使用该参数将枚举的Type传递给转换器。转换器仅对该参数调用Enum.GetNames,并返回结果。实际的Binding将实际上绑定到DataContext中的ComboBox上。 EnumConverter只是很乐意忽略它,而是对参数进行操作。


更新

通过直接绑定到类型,完全跳过ConverterParameter,效果更好,就像这样:

<ComboBox ItemsSource="{Binding Source={x:Type local:MyEnum1}, Converter={StaticResource EnumConverter}}" />

对转换器进行了调整:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    return Enum.GetValues((Type)value);
}

相同的结果,更少的输入,更易于理解的代码。