4

如何将枚举设置为 xaml 中的列表框。但是在列表框中,我需要显示描述而不是枚举的名称/值。然后,当我单击一个按钮时,我需要通过 icommand 将选定的枚举作为枚举而不是字符串传递给方法。例如:

  public enum MyEnum 
  {
     EnumOne = 0,
     [Description("Enum One")]
     EnumTwo = 1,
     [Description("Enum Two")]
     EnumTwo = 2,
     [Description("Enum Three")]
  }

需要将这些枚举绑定到具有描述的 displaymemberpath 的列表框。然后在列表框中进行选择后,像这样传入选定的枚举:

  private void ButtonDidClick(MyEnum enum)
  {

  }

XAML:

  <ListBox ItemsSource="{Binding MyEnum"} /> ?

而且我知道如何将命令连接到按钮..等等。感谢您的帮助。

4

3 回答 3

5

使用 ObjectDataProvider:

<ObjectDataProvider x:Key="enumValues"
   MethodName="GetValues" ObjectType="{x:Type System:Enum}">
      <ObjectDataProvider.MethodParameters>
           <x:Type TypeName="local:ExampleEnum"/>
      </ObjectDataProvider.MethodParameters>
 </ObjectDataProvider>

然后绑定到静态资源:

ItemsSource="{Binding Source={StaticResource enumValues}}"

在这里找到了这个解决方案

于 2015-01-27T15:02:33.507 回答
5

从一个生产应用程序
得到这个不久前,找不到源
将DisplayMememberPath绑定到值

public static Dictionary<T, string> EnumToDictionary<T>()
    where T : struct
{
    Type enumType = typeof(T);

    // Can't use generic type constraints on value types,
    // so have to do check like this
    if (enumType.BaseType != typeof(Enum))
        throw new ArgumentException("T must be of type System.Enum");
    Dictionary<T, string> enumDL = new Dictionary<T, string>();
    foreach (T val in Enum.GetValues(enumType))
    {
        enumDL.Add(val, val.ToString());
    }
    return enumDL;
}

GetDescription 方法

对于那些想知道如何读取描述属性值的人。以下内容可以很容易地转换为使用enum或扩展。我发现这个实现更灵活。

使用此方法,替换val.ToString()GetDescription(val).

    /// <summary>
    /// Returns the value of the 'Description' attribute; otherwise, returns null.
    /// </summary>
    public static string GetDescription(object value)
    {
        string sResult = null;

        FieldInfo oFieldInfo = value.GetType().GetField(value.ToString());

        if (oFieldInfo != null)
        {
            object[] oCustomAttributes = oFieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), true);

            if ((oCustomAttributes != null) && (oCustomAttributes.Length > 0))
            {
                sResult = ((DescriptionAttribute)oCustomAttributes[0]).Description;
            }
        }
        return sResult;
    }
于 2013-08-16T02:27:32.800 回答
1

您可以通过将 Enum 转换为 MyEnum 字符串元组列表并使用 ListBox 的 DisplayMemberPath 参数来显示描述项来实现。当你选择一个特定的元组时,只需抓住它的 MyEnum 部分,并使用它来设置 ViewModel 中的 SelectedEnumValue 属性。

这是代码:

XAML:

<Window x:Class="EnumToListBox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <ListBox Grid.Row="0" 
             ItemsSource="{Binding EnumToDescriptions}"
             SelectedItem="{Binding SelectedEnumToDescription}"
             DisplayMemberPath="Item2"/>
    <TextBlock Grid.Row="1" 
               Text="{Binding SelectedEnumToDescription.Item2}"/>
</Grid>

代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new ViewModel();
    }
}

public class ViewModel : PropertyChangedNotifier
{
    private List<Tuple<MyEnum, string>> _enumToDescriptions = new List<Tuple<MyEnum, string>>();
    private Tuple<MyEnum, string> _selectedEnumToDescription;

    public ViewModel()
    {
        Array Values = Enum.GetValues(typeof(MyEnum));
        foreach (var Value in Values)
        {
            var attributes = Value.GetType().GetField(Value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
            var attribute = attributes[0] as DescriptionAttribute;
            _enumToDescriptions.Add(new Tuple<MyEnum, string>((MyEnum)Value, (string)attribute.Description));
        }
    }

    public List<Tuple<MyEnum, string>> EnumToDescriptions
    {
        get
        {
            return _enumToDescriptions;
        }
        set
        {
            _enumToDescriptions = value;
            OnPropertyChanged("EnumToDescriptions");
        }
    }

    public Tuple<MyEnum, string> SelectedEnumToDescription
    {
        get
        {
            return _selectedEnumToDescription;
        }
        set
        {
            _selectedEnumToDescription = value;
            SelectedEnumValue = _selectedEnumToDescription.Item1;
            OnPropertyChanged("SelectedEnumToDescription");
        }
    }

    private MyEnum? _selectedEnumValue;
    public MyEnum? SelectedEnumValue
    {
        get
        {
            return _selectedEnumValue;
        }
        set
        {
            _selectedEnumValue = value;
            OnPropertyChanged("SelectedEnumValue");
        }
    }
}

public enum MyEnum
{
    [Description("Item1Description")]
    Item1,
    [Description("Item2Description")]
    Item2,
    [Description("Item3Description")]
    Item3,
    [Description("Item4Description")]
    Item4
}

public class PropertyChangedNotifier : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
于 2013-08-15T23:37:47.760 回答