WPF -Enum的三种绑定方法

一、使用ObjectDataProvider

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<Window
  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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
    }
}
1
使用方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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>
1
  

三、使用扩展的Markup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[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);
 
   }
 
}
1
  
1
使用方法:
1
2
3
<ListBox Name="myComboBox" SelectedIndex="0" Margin="8"
 
              ItemsSource="{my:EnumValues HorizontalAlignment}"/>

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

为Enum类型自定义Attribute

从而实现Enum与资源关联

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/// <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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/// <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
}

使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<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

posted @   霍旭东  阅读(3281)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示