• WPF -Enum的三种绑定方法


    一、使用ObjectDataProvider

    <Window
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:sys="clr-namespace:System;assembly=mscorlib"
      SizeToContent="WidthAndHeight"
      Title="Show Enums in a ListBox using Binding">
     
      <Window.Resources>
        <ObjectDataProvider MethodName="GetValues"
                            ObjectType="{x:Type sys:Enum}"
                            x:Key="AlignmentValues">
          <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="HorizontalAlignment" />
          </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
      </Window.Resources>
     
      <Border Margin="10" BorderBrush="Aqua"
              BorderThickness="3" Padding="8">
        <StackPanel Width="300">
          <TextBlock>Choose the HorizontalAlignment
                     value of the Button:</TextBlock>
          <ListBox Name="myComboBox" SelectedIndex="0" Margin="8"
                   ItemsSource="{Binding Source={StaticResource
                                                 AlignmentValues}}"/>
          <Button Content="Click Me!"
                  HorizontalAlignment="{Binding ElementName=myComboBox,
                                                Path=SelectedItem}"/>
        </StackPanel>
      </Border>
    </Window>

    BindToEnum

    二、使用Converter

    public class RadioButtonCheckedConverter: IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, 
            System.Globalization.CultureInfo culture)
        {
            return value.Equals(parameter);
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, 
            System.Globalization.CultureInfo culture)
        {
            return value.Equals(true) ? parameter : Binding.DoNothing;
        }
    }
    使用方法:
    <RadioButton GroupName="EnumGroup"
        IsChecked="{Binding EnumProperty, Converter={StaticResource RadioButtonCheckedConverter}, 
        ConverterParameter={x:Static src:TestEnum.Option1}}">
    </RadioButton>
    
    <RadioButton GroupName="EnumGroup"  
        IsChecked="{Binding EnumProperty, Converter={StaticResource RadioButtonCheckedConverter}, 
        ConverterParameter={x:Static src:TestEnum.Option2}}">
    </RadioButton>
    
    <RadioButton GroupName="EnumGroup"  
        IsChecked="{Binding EnumProperty, Converter={StaticResource RadioButtonCheckedConverter}, 
        ConverterParameter={x:Static src:TestEnum.Option3}}">
    </RadioButton>
     

    三、使用扩展的Markup

    [MarkupExtensionReturnType(typeof(IEnumerable))]
    
    public class EnumValuesExtension : MarkupExtension
    
    {
    
       public EnumValuesExtension()
    
       {
    
       }
    
       public EnumValuesExtension(Type enumType)
    
       {
    
           this.EnumType = enumType;
    
       }
    
       [ConstructorArgument("enumType")]
    
       public Type EnumType { get; set; }
    
       public override object ProvideValue(IServiceProvider serviceProvider)
    
       {
    
           if (this.EnumType == null)
    
               throw new ArgumentException("The enum type is not set");
    
           return Enum.GetValues(this.EnumType);
    
       }
    
    }
     
    使用方法:
    <ListBox Name="myComboBox" SelectedIndex="0" Margin="8"
    
                  ItemsSource="{my:EnumValues HorizontalAlignment}"/>

    四、使用资源文件实现Enum本地化

    为Enum类型自定义Attribute

    从而实现Enum与资源关联

        /// <summary>
        /// Attribute for localization.
        /// </summary>
        [AttributeUsage(AttributeTargets.All,Inherited = false,AllowMultiple = true)]
        public sealed class LocalizableDescriptionAttribute : DescriptionAttribute
        {
            #region Public methods.
            // ------------------------------------------------------------------
    
            /// <summary>
            /// Initializes a new instance of the 
            /// <see cref="LocalizableDescriptionAttribute"/> class.
            /// </summary>
            /// <param name="description">The description.</param>
            /// <param name="resourcesType">Type of the resources.</param>
            public LocalizableDescriptionAttribute
    		(string description,Type resourcesType) : base(description)
            {
                _resourcesType = resourcesType;
            }
    
            #endregion
    
            #region Public properties.
    
            /// <summary>
            /// Get the string value from the resources.
            /// </summary>
            /// <value></value>
            /// <returns>The description stored in this attribute.</returns>
            public override string Description
            {
                get
                {
                    if (!_isLocalized)
                    {
                        ResourceManager resMan =
                             _resourcesType.InvokeMember(
                             @"ResourceManager",
                             BindingFlags.GetProperty | BindingFlags.Static |
                             BindingFlags.Public | BindingFlags.NonPublic,
                             null,
                             null,
                             new object[] { }) as ResourceManager;
    
                        CultureInfo culture =
                             _resourcesType.InvokeMember(
                             @"Culture",
                             BindingFlags.GetProperty | BindingFlags.Static |
                             BindingFlags.Public | BindingFlags.NonPublic,
                             null,
                             null,
                             new object[] { }) as CultureInfo;
    
                        _isLocalized = true;
    
                        if (resMan != null)
                        {
                            DescriptionValue =
                                 resMan.GetString(DescriptionValue, culture);
                        }
                    }
    
                    return DescriptionValue;
                }
            }
            #endregion
    
            #region Private variables.
    
            private readonly Type _resourcesType;
            private bool _isLocalized;
    
            #endregion
        }

    实现自定义的Converter

        /// <summary>
        /// This class simply takes an enum and uses some reflection to obtain
        /// the friendly name for the enum. Where the friendlier name is
        /// obtained using the LocalizableDescriptionAttribute, which holds the localized
        /// value read from the resource file for the enum
        /// </summary>
        [ValueConversion(typeof(object), typeof(String))]
        public class EnumToFriendlyNameConverter : IValueConverter
        {
            #region IValueConverter implementation
    
            /// <summary>
            /// Convert value for binding from source object
            /// </summary>
            public object Convert(object value, Type targetType,
                    object parameter, CultureInfo culture)
            {
                // To get around the stupid WPF designer bug
                if (value != null)
                {
                    FieldInfo fi = value.GetType().GetField(value.ToString());
    
                    // To get around the stupid WPF designer bug
                    if (fi != null)
                    {
                        var attributes =
                            (LocalizableDescriptionAttribute[]) 
    			fi.GetCustomAttributes(typeof 
    			(LocalizableDescriptionAttribute), false);
    
                        return ((attributes.Length > 0) &&
                                (!String.IsNullOrEmpty(attributes[0].Description)))
                                   ?
                                       attributes[0].Description
                                   : value.ToString();
                    }
                }
    
                return string.Empty;
            }
    
            /// <summary>
            /// ConvertBack value from binding back to source object
            /// </summary>
            public object ConvertBack(object value, Type targetType, 
    			object parameter, CultureInfo culture)
            {
                throw new Exception("Cant convert back");
            }
            #endregion
        }

    使用方法:

    <ComboBox x:Name="cmbFoodType"  
        ItemsSource="{Binding Source={StaticResource foodData}}"
        SelectedItem="{Binding Path=TestableClass.FoodType, Mode=TwoWay}" Height="Auto">
        <ComboBox.ItemTemplate>
    
            <DataTemplate>
                <Label  Content="{Binding   Path=.,Mode=OneWay, 
                                    Converter={StaticResource enumItemsConverter}}"
                        Height="Auto"
                        Margin="0" 
                        VerticalAlignment="Center"/>
    
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

    参考

    Binding and Using Friendly Enums in WPF

    Displaying Enum Values using Data Binding

    Binding Radio Buttons to a Single Property

  • 相关阅读:
    java 23种设计模式及具体例子 收藏有时间慢慢看
    java中的内存一般分成几部分?
    深入浅出Java垃圾回收机制
    HashMap、HashTable、LinkedHashMap和TreeMap用法和区别
    java 序列化与反序列化
    JAVA中int、String的类型相互转换
    java IO和NIO 的区别
    数据库设计
    服务器硬件优化
    系统配置优化
  • 原文地址:https://www.cnblogs.com/HQFZ/p/4720534.html
Copyright © 2020-2023  润新知