将枚举绑定到复选框和按位运算

发布于 2024-12-09 09:59:10 字数 2196 浏览 6 评论 0原文

在 Silverlight Web 应用程序中,我有一个服务及其接口,我在其中声明了一个带有星期几的枚举:

[Serializable]
[DataContract]
[Flags]
public enum WeekDaysFlags : int {
[EnumMember]
Monday = 1,
[EnumMember]
Tuesday = 2,
[EnumMember]
Wednesday = 4,
[EnumMember]
Thursday = 8,
etc.

回到应用程序,我有一个我想要绑定的每一天的复选框;我确实制作了一个漂亮的转换器,它接受一个参数:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int d;
            if (int.TryParse(parameter.ToString(), out d))
            {
                WeekDaysFlags mask = WeekDaysFlags.Monday;
                switch (d)
                {
                    case 0:
                        mask = WeekDaysFlags.Sunday;
                        break;
                    case 1:
                        mask = WeekDaysFlags.Monday;
                        break;
                    case 2:
                        mask = WeekDaysFlags.Tuesday;
                        break;
                    case 3:
                        mask = WeekDaysFlags.Wednesday;
                        break;
                    case 4:
                        mask = WeekDaysFlags.Thursday;
                        break;
                    case 5:
                        mask = WeekDaysFlags.Friday;
                        break;
                    case 6:
                        mask = WeekDaysFlags.Saturday;
                        break;
                }

                WeekDaysFlags day = (WeekDaysFlags)value;
                return (day & mask) == day;
            }

            return false;
        }

然后复选框的 IsChecked 属性接收如下所示的内容,每天的参数为 0 到 6。

IsChecked="{Binding WeeksDays, Mode=TwoWay, Converter={StaticResource DayOfWeekConverter}, ConverterParameter=1}"

然后我运行我的程序,读取数据库,绑定对象 aaaa...什么都没有!我希望检查星期一和星期三,因为 WeekDays 变量包含 5。 当我调试时,我确实使用正确的值和正确的参数进入转换器,它确实在应该返回 true 或 false 时返回 true 或 false,但在 UI 中,没有选中任何复选框。不理解...

目前,因为我需要它工作,所以我从后面的代码手动分配 IsChecked...

如果你有一个解决方案,那就太好了!另外,我想知道当我需要“读取”选中的复选框时,绑定将如何工作;即如何获得“星期一|”星期三 |星期四',或 13,或复选框中的绑定变量中的任何内容 /me scrap head

谢谢您的帮助;)

Sylvain

In a Silverlight Web app, I have a service and its interface in where I declared an Enum with the days of the week:

[Serializable]
[DataContract]
[Flags]
public enum WeekDaysFlags : int {
[EnumMember]
Monday = 1,
[EnumMember]
Tuesday = 2,
[EnumMember]
Wednesday = 4,
[EnumMember]
Thursday = 8,
etc.

Back in the application, I have a checkbox for each day that I would like to bind; I did make a pretty converter that accepts a parameter:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int d;
            if (int.TryParse(parameter.ToString(), out d))
            {
                WeekDaysFlags mask = WeekDaysFlags.Monday;
                switch (d)
                {
                    case 0:
                        mask = WeekDaysFlags.Sunday;
                        break;
                    case 1:
                        mask = WeekDaysFlags.Monday;
                        break;
                    case 2:
                        mask = WeekDaysFlags.Tuesday;
                        break;
                    case 3:
                        mask = WeekDaysFlags.Wednesday;
                        break;
                    case 4:
                        mask = WeekDaysFlags.Thursday;
                        break;
                    case 5:
                        mask = WeekDaysFlags.Friday;
                        break;
                    case 6:
                        mask = WeekDaysFlags.Saturday;
                        break;
                }

                WeekDaysFlags day = (WeekDaysFlags)value;
                return (day & mask) == day;
            }

            return false;
        }

Then the IsChecked property of the checkboxes receives something like below, with parameters from 0 to 6 for each day.

IsChecked="{Binding WeeksDays, Mode=TwoWay, Converter={StaticResource DayOfWeekConverter}, ConverterParameter=1}"

Then I run my program, read the database, bind the object aaaaand... nothing! I expect to have monday and wednesday checked since the WeekDays variable contains 5.
When I debug, I do step into the converter with right value and the right parameter, it does return true or false when it is supposed to do so, but in the UI, none of the checkbox is checked. No comprendo...

For the moment, since I need it to work, I assign IsChecked manually from the code behind...

If you have a solution, that would be great! Also I wonder how the binding will work when I will need to "read" the checked checkboxes; i.e. how to get 'Monday | Wednesday | Thursday', or 13, or whatever in my binded variable from the checkboxes /me scratch head

Thank you for your help ;)

Sylvain

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

感性不性感 2024-12-16 09:59:10

对于初学者来说:-

return (day & mask) == day;

应该是

return (day & mask) == mask;

我会更进一步并说你应该使用 Enum.Parse 来查看。这将允许您在 ConvertParameter 分配中使用“Sunday”、“Monday”等日词。这将使 Xaml 更具可读性并消除丑陋的 switch 构造。

您知道这只有一种方法吗?如果用户选择/取消选择组合框,则无法使用此转换器方法来更新位字段。这是因为需要能够读取位域的当前状态来更新它,但 IValueConverter 中的反向转换无法发现该值的当前状态。

Well for starters this:-

return (day & mask) == day;

should be

return (day & mask) == mask;

I'd take this further and say you should look a using Enum.Parse. That will allow you to use day words like "Sunday", "Monday" in your ConvertParameter assignments. This would make the Xaml more readable and eliminate the ugly switch construct.

You understand that this only works one way? You can't use this converter approach to update a bit field if the user selects/deselects the combobox. This is due to the need to be able to read the current state of the bitfield to update it but the reverse convert in IValueConverter can't discover the current state of the value.

最偏执的依靠 2024-12-16 09:59:10

整个位掩码转换器设置给我的印象是过度设计。很难做到正确,而且不太灵活。

考虑将枚举解压到 ViewModel 上的布尔数组中。将其设置为 (bool, string) 列表,然后您可以使用 CheckBox 模板将其绑定到 ItemsControl。不再有重复的代码和标记。

The whole bitmask-converter setup strikes me as over-engineering. It will be difficult to get right and it is not very flexible.

Consider unpacking your enum into an array of booleans on your ViewModel. Make it a List of (bool, string) and you can bind it to an ItemsControl with a CheckBox template. No more repeated code and markup.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文