一尘不染

MVVM:将单选按钮绑定到视图模型吗?

c#

编辑: .NET 4.0中已解决问题。

我一直在尝试使用IsChecked按钮将一组单选按钮绑定到视图模型。查看其他帖子后,该IsChecked属性似乎根本无法正常工作。我整理了一个简短的演示来重现该问题,下面将对此进行介绍。

这是我的问题:是否有使用MVVM绑定单选按钮的简单可靠的方法?谢谢。

附加信息:IsChecked属性不起作用有两个原因:

  1. 选择按钮后,组中其他按钮的IsChecked属性不会设置为 false

  2. 当选择一个按钮时,第一次选择该按钮后,不会设置其自己的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

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首次单击按钮后,两个按钮的属性都不会更新。


阅读 310

收藏
2020-05-19

共1个答案

一尘不染

如果您从Jason的建议开始,那么问题将成为列表中的一个单一边界选择,该列表非常好地转换为ListBox。那时,将样式应用于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>
2020-05-19