WPF组合框/多选带有ListBox的基础上枚举与旗(WPF ComboBox/ListBox wi

2019-07-21 21:01发布

所以,我可以只需按下界限有点...

基本上,我有以下枚举,在C#代码中声明:

[Flags]
public enum FlaggedEnum : int
{
    Option1 = 1,
    Option2 = 2,
    Option3 = 4,
    Option4 = 8,
    ...
    Option16 = 32768,
    None = 0
}

该枚举是我已经成功绑定到DataGrid对象的对象的成员。 成功意味着我已经成功绑定所有其他领域。 :)

我想在这里实现是所有适当的选项上面进行检查,其行为和行为像一个组合框/列表框控件。 所以,你点击字段和下拉菜单与以“检查”取其所需选项的能力弹出。

控制也将必须能够从枚举读写一个枚举。

我是一个新手WPF,所以我不知道从何处创建一个ComboBox,并结合柱去除了...任何帮助,将不胜感激!

Answer 1:

我有可能的工作方式。 我不采取任何信用这一点 - 我在网上找到了这种方法,忘了保存地址。

在我的项目,我需要一些复选框绑定到一个标志枚举。 为了帮助,我发现了一个简单的值转换器的实现,以促进双向绑定。 它不是通用的,转换器的单个实例只能一次一个目标(意思是价值和组复选框中的一个实例)工作。 该转换器使用存储的参考值,以此来转换回,因此,如果您尝试不同的对象实例之间重复使用它,它不会工作。 这就是说,这是唯一使用我有这样的事情,它的工作就像一个魅力。

该转换器:

/// <summary>
/// Provides for two way binding between a TestErrors Flag Enum property and a boolean value.
/// TODO: make this more generic and add it to the converter dictionary if possible
/// </summary>
public class TestActionFlagValueConverter : IValueConverter {
    private TestErrors target;

    public TestActionFlagValueConverter() {

    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        TestErrors mask = (TestErrors)parameter;
        this.target = (TestErrors)value;
        return ((mask & this.target) != 0);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        this.target ^= (TestErrors)parameter;
        return this.target;
    }
}

在XAML它正是如此使用:

<StackPanel.Resources>
    <local:TestActionFlagValueConverter x:Key="TestActionFlagValueConverter"/>
</StackPanel.Resources>

<CheckBox IsChecked="{Binding Errors, Converter={StaticResource TestActionFlagValueConverter}, ConverterParameter={x:Static local:TestErrors.PowerFailure}...
<CheckBox IsChecked="{Binding Errors, Converter={StaticResource TestActionFlagValueConverter}, ConverterParameter={x:Static local:TestErrors.OpenCondition}...

在你的情况,你可能把这个到您的DATACELL模板(虽然很明显,你可能更喜欢使用ComboBox ragther不是一个简单的StackPanel。确保实例接近你的复选框组容器的转换器,以确保他们有自己的转换器的实例。

编辑:

在这里,我做了一个小测试项目与一个DataGrid的组合框以此来证明,它是基于关闭默认的WPF应用程序 - 只要确保引用WPF工具。

这里是Window1.xaml文件:

<Window 
    x:Class="FlagEnumTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Controls="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
    xmlns:FlagEnumTest="clr-namespace:FlagEnumTest"
    Title="Window1" Height="300" Width="300">

    <Window.Resources>
        <x:Array Type="{x:Type FlagEnumTest:TestObject}" x:Key="TestArray">
            <FlagEnumTest:TestObject Errors="OpenCondition" />
            <FlagEnumTest:TestObject />
        </x:Array>
    </Window.Resources>

    <StackPanel>

        <Controls:DataGrid ItemsSource="{Binding Source={StaticResource TestArray}}">
            <Controls:DataGrid.Columns>
                <Controls:DataGridTemplateColumn Header="Errors">
                    <Controls:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox>
                                <ComboBox.Resources>
                                    <FlagEnumTest:TestErrorConverter x:Key="ErrorConverter" />
                                </ComboBox.Resources>
                                <CheckBox Content="PowerFailure" IsChecked="{Binding Path=Errors, Converter={StaticResource ErrorConverter}, ConverterParameter={x:Static FlagEnumTest:TestErrors.PowerFailure}}" />
                                <CheckBox Content="OpenCondition" IsChecked="{Binding Path=Errors, Converter={StaticResource ErrorConverter}, ConverterParameter={x:Static FlagEnumTest:TestErrors.OpenCondition}}" />
                            </ComboBox>
                        </DataTemplate>
                    </Controls:DataGridTemplateColumn.CellTemplate>
                </Controls:DataGridTemplateColumn>
            </Controls:DataGrid.Columns>
        </Controls:DataGrid>

    </StackPanel>
</Window>

这里是Window1.xaml.cs文件的代码隐藏。

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace FlagEnumTest {
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window {
        public Window1() {
            InitializeComponent();
        }
    }

    [Flags]
    public enum TestErrors {
        NoError = 0x0,
        PowerFailure = 0x1,
        OpenCondition = 0x2,
    }

    public class TestObject {
        public TestErrors Errors { get; set; }
    } 

    /// <summary>
    /// Provides for two way binding between a TestErrors Flag Enum property and a boolean value.
    /// TODO: make this more generic and add it to the converter dictionary if possible
    /// </summary>
    public class TestErrorConverter : IValueConverter {
        private TestErrors target;

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            TestErrors mask = (TestErrors)parameter;
            this.target = (TestErrors)value;
            return ((mask & this.target) != 0);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
            this.target ^= (TestErrors)parameter;
            return this.target;
        }
    }

}

默认情况下,DataGrid中会创建自己的列代表以及我的授权模板之一,所以你可以看到文本的表示,以及对应的复选框之一。 标志枚举混淆默认的文本表示,但你仍然可以看到,结合工作正常(同时检查,然后取消勾选你最后一个 - 字符串值更改为另一个,而不是0)。



文章来源: WPF ComboBox/ListBox with MultiSelect based on Enum with Flags