【问题标题】:WPF ObjectDataProvider ParametersWPF ObjectDataProvider 参数
【发布时间】:2018-10-29 16:40:25
【问题描述】:

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

有什么想法吗?

【问题讨论】:

  • 我很确定ObjectDataProvider 不支持这种功能。您需要每种类型的提供者。 ODP 只是作为方法调用的薄包装器。
  • 我认为您可以安装IValueConverter 以获得您想要的功能。给我几分钟试试,如果成功了,我会为你发布答案。

标签: wpf objectdataprovider


【解决方案1】:

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

这会产生以下输出:

这利用了您可以将额外参数传递给IValueConverter 的事实,我用它来将枚举的Type 传递给转换器。转换器只是在该参数上调用Enum.GetNames,并返回结果。实际的Binding 实际上将绑定到ComboBox 中的DataContextEnumConverter 只是愉快地忽略它并改为对参数进行操作。


更新

直接绑定到类型会更好,完全跳过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);
}

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

【讨论】:

  • 这可行,但与使用 ObjectDataProvider 略有不同。使用 ObjectDataProvider,ComboBox 显示 ComboBox 绑定的数据的当前值,但使用 Converter,它只显示空白。
  • 这只是因为我从您的代码中删除了 SelectedItem 绑定以保持我的示例简单。这与ObjectDataProvider 完全无关。如果您使用原始代码中的绑定,它应该 工作。如果您尝试这样做,但它不起作用,请告诉我,我会尝试弄清楚发生了什么。
  • 我仍然有 SelectedItem 在那里,就像在我的原始代码中一样。
  • 好的,我会试着弄清楚为什么这不起作用。我没有任何理由认为它不起作用
  • 啊,我突然想到了问题所在。我的转换器返回的是 strings 列表,而不是枚举 values 列表。由于绑定属性是实际的枚举值,因此无法找到匹配项。这是一个简单的修复。只需将转换器中的返回语句更改为return Enum.GetValues((Type)value);。我现在正在更新答案。
猜你喜欢
  • 1970-01-01
  • 2012-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多