2

我有一个 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 声明中对其进行硬编码。

有任何想法吗?

4

1 回答 1

2

ObjectDataProvider不支持这种功能,但您可以通过巧妙地滥用aBinding和 an来“伪造”它IValueConverter

首先,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,
}

这会产生以下输出: 在此处输入图像描述 在此处输入图像描述

这利用了您可以将额外参数传递给 an 的事实,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);
}

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

于 2018-10-29T17:22:22.823 回答