在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}"
然后我运行我的程序,读取数据库,绑定对象aaaaand ......什么都没有!由于WeekDays变量包含5,我希望星期一和星期三检查。 当我调试时,我会使用正确的值和正确的参数进入转换器,当它应该这样做时它会返回true或false,但是在UI中,没有选中复选框。没有改编......
目前,由于我需要它工作,我从后面的代码手动分配IsChecked ...
如果你有解决方案,那就太好了!另外我想知道当我需要“读取”选中的复选框时绑定是如何工作的;即如何获得'星期一|星期三|星期四',或13,或者来自复选框 / me scratch head
的绑定变量中的任何内容感谢您的帮助;)
西尔
答案 0 :(得分:2)
对于初学者来说: -
return (day & mask) == day;
应该是
return (day & mask) == mask;
我会更进一步说你应该看一下使用Enum.Parse
。这样您就可以在ConvertParameter
作业中使用“星期日”,“星期一”等日期字词。这将使Xaml更具可读性并消除丑陋的switch
构造。
你明白这只能单向运作吗?如果用户选择/取消选择组合框,则无法使用此转换器方法更新位字段。这是因为需要能够读取位域的当前状态以更新它,但IValueConverter
中的反向转换无法发现值的当前状态。
答案 1 :(得分:1)
整个位掩码转换器设置让我感到过度工程化。它很难做到正确,而且不是很灵活。
考虑将您的枚举解压缩到ViewModel上的一组布尔值中。使其成为(bool,string)的列表,您可以使用CheckBox模板将其绑定到ItemsControl。不再重复代码和标记。