将CheckBox绑定到枚举值

时间:2020-11-02 22:33:39

标签: c# wpf

这似乎是一个非常基本的想法,我只是无法在任何地方找到答案。我想将枚举类型或类绑定到类似于使用ComboBox可以完成的复选框。例如:

public class MyClass
{
    public int Value {get; set;}
    public string Display {get; set;}
}

然后在XAML中将其绑定到如下类:

<ComboBox x:Name="comboBoxMyCb" ItemsSource="{Binding ListOfMyClass}" DisplayMemberPath="Display" SelectedValuePath="Value"/>

然后,当事件发生时,我可以稍后获取值,如下所示:

int val = (int)comboBoxMyCb.SelectedValue;

基本上,我想做类似的事情,但是更简单。我正在列出一个枚举值,每个值对应一个复选框。我当前的设置是当我关闭窗口时,检查哪些复选框已选中,并将其对应的枚举值添加到列表中。这使很多if语句成为可能,因为它们可以超过40个复选框。我想做的是将每个复选框绑定到XAML中的一个枚举值,然后将每个onclick事件设置为一个类似于以下内容的函数:

private void CheckBoxItem_Click(object sender, RoutedEventArgs e)
{
    CheckBox cb = (CheckBox)sender;
    MyEnum value = (MyEnum)cb.value;//or whatever
    if (cb.IsChecked == true)
    {
        EnumList.add(value)
    }
    else
    {
        EnumList.remove(value);
    }
}

我知道某些代码不是最佳的,我只是以示例的方式编写了所有代码。 谢谢您的帮助

2 个答案:

答案 0 :(得分:2)

您可以编写一个包装类来表示您的Enum。例如,考虑示例枚举

public enum SampleEnum
{
        [Description("Description 01")]
        Sample01,
        [Description("Description 02")]
        Sample02,
        [Description("Description 03")]
        Sample03
} 

现在您可以将包装器写为

public class Wrapper
{
        public SampleEnum Value { get; set; }
        public string Description => GetEnumDescription(Value);
        public bool IsSelected { get; set; }

        private string GetEnumDescription(Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());
            DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

            if (attributes.Length > 0)
                return attributes[0].Description;
            else
                return value.ToString();
        }
}

您现在可以在视图模型中创建收藏集

public List<Wrapper> EnumCollection { get; set; } 

可以初始化为

EnumCollection = Enum.GetValues(typeof(SampleEnum))
                .Cast<SampleEnum>()
                .Select(x => new Wrapper { Value = x, }).ToList();

此收藏集现在可以绑定到您的Checkbox收藏夹。例如,

<ItemsControl ItemsSource="{Binding EnumCollection}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <CheckBox Content="{Binding Description}" IsChecked="{Binding IsSelected}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
</ItemsControl>

IsSelected标志将帮助您跟踪是否选择了特定的枚举。

答案 1 :(得分:1)

如果要在XAML中创建每个CheckBox,则可以将枚举类型分配给Tag属性。

获取或设置一个任意的对象值,该值可用于存储有关此元素的自定义信息。

我用常量MyEnum创建了一个枚举MyEnumConstant1,依此类推,用您自己的常量替换。

<CheckBox Content="My enum constant 1" Tag="{x:Static local:MyEnum.MyEnumConstant1}" Checked="EnumCheckBoxChecked"/>
<CheckBox Content="My enum constant 2" Tag="{x:Static local:MyEnum.MyEnumConstant2}" Checked="EnumCheckBoxChecked"/>
<!-- ...the other 38 check boxes. -->

使用Checked事件,您可以获得Tag并将枚举值添加到EnumList或将其删除。由于我不知道您的EnumList是什么,因此我将其保留为此示例代码中的内容。

private void EnumCheckBoxChecked(object sender, RoutedEventArgs e)
{
   var checkBox = (CheckBox)sender;
   var value= checkBox.Tag;

   if (checkBox.IsChecked.GetValueOrDefault())
   {
      EnumList.add(value);
   }
   else
   {
      EnumList.remove(value);
   }
}

IsChecked属性是可为空的bool。如果GetValueOrDefaultfalse,则会返回null

您还可以通过使用视图模型并绑定到命令,以符合MVVM的方式执行此操作。

<CheckBox Content="My enum value 1" Command="{Binding CheckedCommand}" CommandParameter="{x:Static local:MyEnum.MyEnumValue1}"/>

这里,您不需要Tag属性,因为您将枚举常量作为命令参数传递。