WPF 组合框/列表框,具有基于带有标志的枚举的多重选择
所以我可能有点突破了界限...
基本上我有以下枚举,在 C# 代码中声明:
[Flags]
public enum FlaggedEnum : int
{
Option1 = 1,
Option2 = 2,
Option3 = 4,
Option4 = 8,
...
Option16 = 32768,
None = 0
}
该枚举是我已成功绑定到 DataGrid 对象的对象的成员。成功意味着我已经成功绑定了所有其他字段。 :)
我想要在这里实现的是一个控件,其中检查了上面所有适当的选项,其行为和作用类似于组合框/列表框。因此,您单击该字段,会弹出一个下拉菜单,可以“检查”所需的选项。
该控件还必须能够读取枚举并写入枚举。
我是 WPF 新手,所以除了创建 ComboBox 和绑定到列之外,我不知道该去哪里......任何帮助将不胜感激!
So I may be pushing the boundaries just a bit...
Basically I have the following enum, declared in C# code:
[Flags]
public enum FlaggedEnum : int
{
Option1 = 1,
Option2 = 2,
Option3 = 4,
Option4 = 8,
...
Option16 = 32768,
None = 0
}
This enum is a member of an object which I have successfully bound to a DataGrid object. Successfully meaning that I have bound all the other fields successfully. :)
What I want to achieve here is a control where all the appropriate options above are checked, that behaves and acts like a ComboBox/ListBox. So you click on the field and a drop-down menu pops up with the ability to "check" whichever options are required.
The control will also have to be able to read from the enum and write an enum.
I'm a WPF novice so I have no idea where to go apart from creating a ComboBox and binding to the column... Any help would be appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我有一个方法可能有效。我对此没有任何功劳 - 我在网上找到了这个方法,但忘记保存地址。
在我的项目中,我需要将一些复选框绑定到标志枚举。为了提供帮助,我找到了一个简单的值转换器的实现来促进双向绑定。它不是通用的,并且转换器的单个实例一次只能与一个目标(意味着一个值的一个实例及其一组复选框)一起工作。转换器使用存储的值引用作为转换回来的方式,因此如果您尝试在单独的对象实例之间重用它,它将无法工作。也就是说,这是我对此类东西的唯一用途,而且它的作用就像一个魅力。
转换器:
在 xaml 中,它是这样使用的:
在您的情况下,您可以将其放入数据单元模板中(尽管显然您可能更喜欢使用组合框而不是简单的堆栈面板)。请确保实例化靠近复选框组容器的转换器确保他们有自己的转换器实例。
编辑:
这里,我做了一个小测试项目来演示在带有数据网格的组合框中使用它,它基于默认的 WPF 应用程序 - 只需确保在
此处 引用 WPF 工具包。是 Window1.xaml 文件:
这里是 Window1.xaml.cs 文件代码隐藏
默认情况下,数据网格将创建自己的列表示以及我的强制模板表示,因此您可以看到文本表示以及复选框一。标志枚举混淆了默认文本表示,但您仍然可以看到绑定正常工作(选中两个,然后取消选中最后一个 - 字符串值更改为另一个,而不是 0)。
I have a way that might work. I take no credit for this - I found this method on the web, and forgot to save the address.
In my project I needed to bind a few checkboxes to a flag enum. To help, I found an implementation of a simple value converter to facilitate two way binding. It's not generic, and a single instance of a converter can only work with one target (meaning one instance of a value and its group of checkboxes) at a time. The converter uses a stored reference to the value as a way to convert back, so if you try to reuse it between separate object instances it won't work. That said, this is the only use i had for something like this and it worked like a charm.
The converter:
In xaml it is used thusly:
In your case you might place this into your datacell template (though obviously you probably prefer to use a combobox ragther than a simple stackpanel. Make sure to instantiate the converter close to your checkbox group container to make sure they have their own instance of the converter.
Edit:
Here, I made a little test project to demonstrate using this in a combobox with a datagrid, it's based off the default WPF application - just make sure to reference the WPF toolkit.
Here is the Window1.xaml file:
And here is the Window1.xaml.cs file codebehind.
By default the datagrid will create its own representation of the column as well as my mandated templated one, so you can see the text representation as well as the checkbox one. The flag enum confuses the default text representation, but you can still see that the binding is working correctly (check both, then uncheck the one you checked last - string value changes to the other one, not 0).
我创建了一个 IValueConverter,它支持直接绑定到枚举,而无需代码隐藏或辅助类。它只有两个限制:
该解决方案基于这样的经验事实:在 ConvertBack 之前总是先有 Convert。如果 ConvertBack 更改了值,则始终存在 Convert。仅当 INotifyPropertyChanged 在模型上正确实现时,此功能才有效。因此,在两次调用之间,最后一个已知值可以存储在转换器中并在 ConvertBack 方法中使用。
转换器实例应该获取枚举的类型以及它是否是 Flags 枚举。
然后可以使用此转换器绑定复选框。
单选按钮可以使用带有 Flags="False" 的实例通过相同的机制进行绑定
转换器的源代码
I have created an IValueConverter that supports binding to the enum directly without codebehind or helper classes. It has only two restrictions:
The solution is based on the empirical fact that there is always a Convert first before a ConvertBack. And there is always a Convert if a ConvertBack has changed the value. This one only works when the INotifyPropertyChanged is properly implemented on the model. So between the two calls the last known value can be stored in the converter and used in the ConvertBack method.
The converter instance should get the Type of the enum and whether it is a Flags enum or not.
Then the checkboxes can be bound using this converter.
Radio buttons can be bound by the same mechanism using an instance with Flags="False"
The source code of the converter