【问题标题】:How do you bind an enum to a dependency property to a combobox in WPF?如何将枚举绑定到 WPF 中的组合框的依赖属性?
【发布时间】:2014-10-25 17:14:51
【问题描述】:

我已经阅读了几篇文章和 stackoverflow 帖子,但我仍然对如何完成这项工作感到有些困惑。

我有一个要绑定到依赖属性的枚举列表,然后绑定到组合框。当我加载程序时,组合框是空的。

一旦这样工作,我想在框中显示名称(即附件)和十六进制作为值。

XAML:

<ComboBox ItemsSource="{Binding BodyTypeFlags}" />

C#:

public enum BodyTypeFlagsTS4
{
    Accessory = 0x0000000A,
    Blush = 0x00000020
}

public BodyTypeFlagsTS4 BodyTypeFlags
{
    get { return (BodyTypeFlagsTS4)GetValue(BodyTypeFlagsProperty); }
    set { SetValue(BodyTypeFlagsProperty, value); }
}

public static readonly DependencyProperty BodyTypeFlagsProperty =
    DependencyProperty.Register("BodyTypeFlags", typeof(BodyTypeFlagsTS4),
    typeof(MainWindow), new PropertyMetadata(default(BodyTypeFlagsTS4)));

编辑: 我已经按照建议完成了,现在我可以在组合框中看到枚举项列表。我有两个问题:

  1. 如果我保持枚举不变(名称 = 十六进制),那么当我单击测试按钮时,什么也没有出现。
  2. 如果我删除 = hex 部分(因此,它只有附件和腮红),那么测试按钮将与附件一起返回 - 每次。即使我选择了腮红。 (我不想更改枚举格式,但这告诉我双向绑定不起作用。)

    public BodyTypeFlagsTS4 BodyTypes
    {
        get { return (BodyTypeFlagsTS4)GetValue(BodyTypesProperty); }
        set { SetValue(BodyTypesProperty, value); }
    }
    
    public static readonly DependencyProperty BodyTypesProperty =
        DependencyProperty.Register("BodyTypes", typeof(BodyTypeFlagsTS4), typeof(MainWindow), new PropertyMetadata());
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Dispatcher.BeginInvoke(new Action(() =>
        {
            System.Windows.MessageBox.Show(System.Enum.GetName(typeof(BodyTypeFlagsTS4), this.BodyTypes));
        }));
    }
    

【问题讨论】:

  • ItemsSource 只能绑定到IEnumerable 类型的属性,不能绑定到枚举。其次,你为什么需要依赖属性?

标签: c# wpf xaml combobox enums


【解决方案1】:

您需要提供ComboBox 的可用值列表。例如:

public BodyTypeFlagsTS4[] AvailableBodyTypeFlags
{
    get { return (BodyTypeFlagsTS4[])Enum.GetValues(typeof(BodyTypeFlagsTS4)); }
}

然后将您的ComboBox 绑定到列表:

<ComboBox ItemsSource="{Binding AvailableBodyTypeFlags}"
          SelectedItem="{Binding BodyTypeFlags}" />

而且您实际上并不需要依赖属性。在您的视图模型中实现INotifyPropertyChanged 就足够了。

【讨论】:

    【解决方案2】:

    试试这个解决方案: Zip with solution

    一般来说,你必须用对象包装你的枚举。 查看注释掉的代码以了解如何检索枚举的名称。

    XAML 代码部分:

        <Grid.Resources>
            <ObjectDataProvider x:Key="tools"
                                MethodName="GetValues"
                                ObjectType="{x:Type sys:Enum}">
                <ObjectDataProvider.MethodParameters>
                    <x:Type TypeName="local:Tool" />
                </ObjectDataProvider.MethodParameters>
            </ObjectDataProvider>
        </Grid.Resources>
        <ComboBox x:Name="cmbTools"
                  ItemsSource="{Binding Source={StaticResource tools}}"
                  SelectedItem="{Binding Path=ToolType, Mode=TwoWay}" />
    

    【讨论】:

    • 这是一个仅链接的答案。 StackOverflow 上的答案是独立且永久的。您应该将代码直接放入答案中,而不是提供将在一个月内失效的临时链接。
    • 我收到此错误:名称空间“clr-namespace:S4S”中不存在名称“BodyTypeFlagsEnum” - 但我清楚地在顶部引用了它:xmlns:local="clr-命名空间:S4S”。它也非常位于 c# 中的该命名空间中。有什么想法吗?
    • 您在问题中命名了枚举 BodyTypeFlagsTS4。请检查枚举名称。在 XAML 中,如果您的应用命名空间声明为 codenamespace S4Scode,则您将本地引用为 xmlns:local="clr-namespace:S4S"
    • 谢谢,我让它工作了。 (这似乎是导致它的 VS 的一个已知错误。)枚举项未按与我拥有它们相同的顺序加载到组合框中的原因是什么? (我按字母顺序排列了它们,但它们不再是了。)
    • 另外,System.Windows.MessageBox.Show(System.Enum.GetName(typeof(BodyTypeFlagsTS4), this.BodyTypes));回来是空的
    猜你喜欢
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 2020-02-07
    • 2018-01-12
    • 2011-08-04
    相关资源
    最近更新 更多