c# - 使用组合框 MVVM 绑定(bind)枚举描述

标签 c# wpf mvvm dependency-properties

嗨,我使用依赖对象将我的组合框与枚举绑定(bind)。我搜索并发现这个解决方案对于 MVVM 来说非常优雅,

我的xml是

   <ComboBox SelectedItem="{Binding Color,Mode=TwoWay}" 
                 l:EnumHelper.Enum="{x:Type l:MyEnum }"></ComboBox>

我的依赖对象是
  public class EnumHelper : DependencyObject
{
    public static Type GetEnum(DependencyObject obj)
    {
        return (Type)obj.GetValue(EnumProperty);
    }

    public static void SetEnum(DependencyObject obj, string value)
    {
        obj.SetValue(EnumProperty, value);
    }

    // Using a DependencyProperty as the backing store for Enum.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty EnumProperty =
        DependencyProperty.RegisterAttached("Enum", typeof(Type), typeof(EnumHelper), new PropertyMetadata(null, OnEnumChanged));

    private static void OnEnumChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var control = sender as ItemsControl;

        if (control != null)
        {
            if (e.NewValue != null)
            {
                var _enum = Enum.GetValues(e.NewValue as Type);
                control.ItemsSource = _enum;
            }
        }
    }


}

我想知道我是否必须阅读枚举描述并使用依赖对象将它们转换回来,我该如何扩展这个帮助类。

最佳答案

我使用与 MarkupExtension 略有不同的方法而不是附加属性:

public sealed class EnumValues : MarkupExtension
{
    private readonly Type _enumType;

    public EnumValues(Type enumType)
    {
        _enumType = enumType;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return Enum.GetValues(_enumType);
    }
}

我觉得这更优雅,因为它更短,我可以写 ItemsSource="{l:EnumValues {l:MyEnum}}" .

至于枚举值描述,我使用转换器:
public sealed class EnumValueToDecriptionConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if(value == null)
        {
            return null;
        }
        var type = value.GetType();
        if(!type.IsEnum)
        {
            return null;
        }
        var field = type.GetField(value.ToString());
        var attr = field.GetCustomAttributes(typeof(DescriptionAttribute), true)
                        .Cast<DescriptionAttribute>()
                        .FirstOrDefault();
        if(attr != null)
        {
            return attr.Description;
        }
        else
        {
            return field.Name;
        }
    }

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

    #endregion
}

所以最后你可以用 XAML 写这个:
<ComboBox SelectedItem="{Binding Color, Mode=TwoWay}" 
          ItemsSource="{l:EnumValues {x:Type l:MyEnum}}">
    <FrameworkElement.Resources>
        <l:EnumValueToDecriptionConverter x:Key="EnumValueToDecriptionConverter" />
    </FrameworkElement.Resources>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Mode=OneTime,
                       Converter={StaticResource EnumValueToDecriptionConverter}}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

你可以定义这个DataTemplate如果您多次需要它,请作为应用程序级别的资源。

关于c# - 使用组合框 MVVM 绑定(bind)枚举描述,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18568747/

相关文章:

c# - 使用XPath读取xml

wpf - IMul​​tiValueConverter 值没问题,但 CommandParameter 为空

wpf - 将桌面桥 UWP 应用与 Win32 应用正确打包

wpf - Caliburn.Micro + Autofac 引导

c# - Windows Phone 8.1 中 MapControl Center 属性的数据绑定(bind)

c# - Assert.IsTrue(false) 正在通过

c# - 使用 Entity Framework (C#) 覆盖 PostgreSql 中的序列

c# - NHibernate QueryOver 的按位运算和扩展方法

wpf - MVVM:ViewModel 中的 CollectionView 或 xaml 中的 CollectionViewSource?

silverlight - Windows Phone 7上的mvvm light动画