我有一个可能可行的方法。我不为此做出任何贡献 - 我在网上找到了这种方法,但忘记保存地址。
在我的项目中,我需要将几个复选框绑定到标志枚举。为了帮助,我找到了一个简单值转换器的实现,以促进双向绑定。它不是通用的,一个转换器的单个实例只能同时处理一个目标(意味着一个值和其一组复选框的实例)。转换器使用存储的值引用作为一种转换方式,因此,如果您尝试在分离的对象实例之间重用它,它将无法工作。话虽如此,这是我对此类东西唯一的用途,而且它像魅力一样工作。
转换器:
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}...
在您的情况下,您可能会将此放入数据单元格模板中(尽管显然您可能更喜欢使用组合框而不是简单的堆栈面板)。确保在复选框组容器附近实例化转换器,以确保它们有自己的转换器实例。
编辑:
这里,我制作了一个小测试项目,演示如何在带有数据网格的组合框中使用它,它基于默认的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 {
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; }
}
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;
}
}
}
默认情况下,数据网格将创建其自己的列表示形式以及我指定的模板形式,因此您可以看到文本表示形式以及复选框表示形式。标志枚举会使默认文本表示形式混淆,但您仍然可以看到绑定正常工作(同时勾选两个,然后取消勾选最后一个 - 字符串值更改为另一个而不是0)。