我试图在我的视图模型中将枚举属性表示为我视图中的一组单选按钮。到现在为止还挺好;我可以用双向MultiBinding
来表达这一点:
(rb1.IsChecked,rb2.IsChecked,rb3.IsChecked)< - > vm.Value
此处使用的多重绑定将具有在(bool, bool, bool) <-> MyValue
之间转换的多转换器;显然,MyValue
类型的(三个)允许值之一是根据bool
true
选择的,反之亦然。
这已经有点不方便了:我无法在视图的Xaml中定义该绑定,因为必须从单个值的侧面定义多绑定。因此,我必须在代码隐藏中定义多重绑定,并使用SetBinding
在我的视图模型的Value
属性上设置它。
现在,我坚持的问题是,我不只是将一组单选按钮绑定到该值,而是两个。因此,我的绑定必须如下所示:
(rbA1.IsChecked,rbA2.IsChecked,rbA3.IsChecked)&lt; - &gt; vm.Value&lt; - &gt; (rbB1.IsChecked,rbB2.IsChecked,rbB3.IsChecked)
问题是,我无法一次使用SetBinding
将多个绑定连接到vm.Value
。
到目前为止,我尝试过的解决方案是:
(rbA1.IsChecked, rbA2.IsChecked, rbA3.IsChecked, rbB1.IsChecked, rbB2.IsChecked, rbB3.IsChecked) <-> vm.Value
形式的绑定。此解决方案的问题是,如果选中其中一个单选按钮(例如,rbB2
),我无法确定rbA2
(未选中)或rbB2
(已选中)是否具有此功能“新的,正确的”价值。SelectedIndex
属性。然后,可以从我的无线电组控件的所有实例方便地将此属性绑定到我的vm.Value
属性。虽然可行,但它需要编写一个新的控件类,我想知道这是否是WPF的唯一方法。rbB1
到rbA1
,rbB2
到rbA2
,依此类推,并使用我的vm.Value
和第一组单选按钮之间只有多重绑定,我会达到预期的效果,但我不喜欢拥有“主广播组”的概念。它会滥用GUI元素进行数据传输。答案 0 :(得分:0)
对转换器和代码隐藏使用复杂的多重绑定不仅会使代码更难调试,而且更难以测试。在我看来,最好将每组单选按钮(标志)表示为视图模型。选中/取消选中任何单选按钮时,评估您的值。
<强>的RadioButtonGroup 强>
public class RadioButtonGroup : ViewModel {
public RadioButtonGroup(string groupName, int count, Action<bool[]> whenAnyChanaged = null) {
RadioButtons = Enumerable.Range(0, count).Select(_ => {
var button = new RadioButton { GroupName = groupName };
button.PropertyChanged += (s, e) => {
if (e.PropertyName == "IsChecked")
whenAnyChanaged(Flags);
};
return button;
}).ToList();
}
public List<RadioButton> RadioButtons { get; private set; }
public bool[] Flags { get { return RadioButtons.Select(rb => rb.IsChecked).ToArray(); } }
}
<强>单选按钮强>
public class RadioButton : ViewModel {
private bool isChecked;
public bool IsChecked {
get { return isChecked; }
set { SetProperty(ref this.isChecked, value); }
}
public string GroupName { get; set; }
}
<强> MainViewModel 强>
public class MainViewModel : ViewModel {
public MainViewModel() {
GroupA = new RadioButtonGroup("A", 10, flags => GroupToggle(flags, GroupB.Flags));
GroupB = new RadioButtonGroup("B", 10, flags => GroupToggle(GroupA.Flags, flags));
}
public RadioButtonGroup GroupA { get; private set; }
public RadioButtonGroup GroupB { get; private set; }
void GroupToggle(bool[] groupA, bool[] groupB) {
MyValue = Evaluate(groupA, groupB);
}
}
查看强>
<Window x:Class="WpfLab.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="{Binding Title}" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="RadioButton">
<RadioButton IsChecked="{Binding IsChecked, Mode=OneWayToSource}" GroupName="{Binding GroupName}"/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0" ItemsSource="{Binding GroupA.RadioButtons}" ItemTemplate="{StaticResource ResourceKey=RadioButton}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<ListBox Grid.Row="1" ItemsSource="{Binding GroupB.RadioButtons}" ItemTemplate="{StaticResource ResourceKey=RadioButton}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
答案 1 :(得分:0)
将VMEnum单独绑定到每个RadioButton(使用单个双向绑定)。每个绑定都应该有CommandParameter它的枚举。像:
<RadioButton IsChecked="{Binding VMEnum, Converter={StaticResource EnumConverter}, ConverterParameter={Enums:VMEnums.FirstRadioButtonGroupA}}" />
在转换器中,