编辑: .NET 4.0中已解决问题。
我一直在尝试使用IsChecked按钮将一组单选按钮绑定到视图模型。查看其他帖子后,该IsChecked属性似乎根本无法正常工作。我整理了一个简短的演示来重现该问题,下面将对此进行介绍。
IsChecked
这是我的问题:是否有使用MVVM绑定单选按钮的简单可靠的方法?谢谢。
附加信息: 该IsChecked属性不起作用有两个原因:
选择按钮后,组中其他按钮的IsChecked属性不会设置为 false 。
当选择一个按钮时,第一次选择该按钮后,不会设置其自己的IsChecked属性。我猜测第一次单击时WPF会破坏绑定。
演示项目: 这是重现问题的简单演示的代码和标记。创建一个WPF项目,并将Window1.xaml中的标记替换为以下内容:
<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" Loaded="Window_Loaded"> <StackPanel> <RadioButton Content="Button A" IsChecked="{Binding Path=ButtonAIsChecked, Mode=TwoWay}" /> <RadioButton Content="Button B" IsChecked="{Binding Path=ButtonBIsChecked, Mode=TwoWay}" /> </StackPanel> </Window>
用以下代码(设置hack)替换Window1.xaml.cs中的代码,该代码设置视图模型:
using System.Windows; namespace WpfApplication1 { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { this.DataContext = new Window1ViewModel(); } } }
现在,将以下代码添加到项目中Window1ViewModel.cs:
Window1ViewModel.cs
using System.Windows; namespace WpfApplication1 { public class Window1ViewModel { private bool p_ButtonAIsChecked; /// <summary> /// Summary /// </summary> public bool ButtonAIsChecked { get { return p_ButtonAIsChecked; } set { p_ButtonAIsChecked = value; MessageBox.Show(string.Format("Button A is checked: {0}", value)); } } private bool p_ButtonBIsChecked; /// <summary> /// Summary /// </summary> public bool ButtonBIsChecked { get { return p_ButtonBIsChecked; } set { p_ButtonBIsChecked = value; MessageBox.Show(string.Format("Button B is checked: {0}", value)); } } } }
要重现此问题,请运行应用程序,然后单击ButtonA。将出现一个消息框,指出Button A的IsChecked属性已设置为 true 。现在选择ButtonB。将出现另一个消息框,说明Button B的IsChecked属性已设置为 true ,但没有消息框表明Button A的IsChecked属性已设置为 false -该属性未更改。
现在,再次单击按钮A。该按钮将在窗口中被选中,但不会出现任何消息框-该IsChecked属性尚未更改。最后,再次单击按钮B,结果相同。IsChecked首次单击按钮后,两个按钮的属性都不会更新。
如果您从Jason的建议开始,那么问题将成为列表中的一个单一边界选择,该列表非常好地转换为ListBox。那时,将样式应用于ListBox控件以使其显示为RadioButton列表很简单。
ListBox
RadioButton
<ListBox ItemsSource="{Binding ...}" SelectedItem="{Binding ...}"> <ListBox.ItemContainerStyle> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <RadioButton Content="{TemplateBinding Content}" IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}"/> </ControlTemplate> </Setter.Value> </Setter> </Style> </ListBox.ItemContainerStyle> </ListBox>