MVVM:将单选按钮绑定到视图模型? [英] MVVM: Binding radio buttons to a view model?

查看:27
本文介绍了MVVM:将单选按钮绑定到视图模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题已在 .NET 4.0 中修复.

Problem was fixed in .NET 4.0.

我一直在尝试使用 IsChecked 按钮将一组单选按钮绑定到视图模型.查看其他帖子后,似乎 IsChecked 属性根本不起作用.我已经整理了一个重现问题的简短演示,我已将其包含在下面.

I have been trying to bind a group of radio buttons to a view model using the IsChecked button. After reviewing other posts, it appears that the IsChecked property simply doesn't work. I have put together a short demo that reproduces the problem, which I have included below.

这是我的问题:有没有一种简单可靠的方法来使用 MVVM 绑定单选按钮?谢谢.

Here is my question: Is there a straightforward and reliable way to bind radio buttons using MVVM? Thanks.

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

Additional information: The IsChecked property doesn't work for two reasons:

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

当一个按钮被选中时,它自己的 IsChecked 属性在第一次被选中后不会被设置.我猜第一次点击时绑定会被 WPF 破坏.

When a button is selected, its own IsChecked property does not get set after the first time the button is selected. I am guessing that the binding is getting trashed by WPF on the first click.

演示项目:这是重现问题的简单演示的代码和标记.创建一个 WPF 项目并将 Window1.xaml 中的标记替换为以下内容:

Demo project: Here is the code and markup for a simple demo that reproduces the problem. Create a WPF project and replace the markup in Window1.xaml with the following:

<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>

将 Window1.xaml.cs 中的代码替换为以下设置视图模型的代码(一个 hack):

Replace the code in Window1.xaml.cs with the following code (a hack), which sets the view model:

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 添加到项目中:

Now add the following code to the project as 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));
            }
        }

    }
}

要重现该问题,请运行应用程序并单击按钮 A.将出现一个消息框,说明按钮 A 的 IsChecked 属性已设置为 true.现在选择按钮 B.将出现另一个消息框,说按钮 B 的 IsChecked 属性已设置为 true,但没有消息框指示按钮 A 的 IsChecked 属性已设置为 false--该属性未更改.

To reproduce the problem, run the app and click Button A. A message box will appear, saying that Button A's IsChecked property has been set to true. Now select Button B. Another message box will appear, saying that Button B's IsChecked property has been set to true, but there is no message box indicating that Button A's IsChecked property has been set to false--the property hasn't been changed.

现在再次单击按钮 A.按钮将在窗口中被选中,但不会出现消息框——IsChecked 属性没有改变.最后,再次单击按钮 B——结果相同.在第一次单击按钮后,任何一个按钮的 IsChecked 属性都不会更新.

Now click Button A again. The button will be selected in the window, but no message box will appear--the IsChecked property has not been changed. Finally, click on Button B again--same result. The IsChecked property is not updated at all for either button after the button is first clicked.

推荐答案

如果您从 Jason 的建议开始,那么问题就变成了从列表中选择的单一绑定选项,该列表非常好地转换为 ListBox.此时,将样式应用到 ListBox 控件使其显示为 RadioButton 列表是微不足道的.

If you start with Jason's suggestion then the problem becomes a single bound selection from a list which translates very nicely to a ListBox. At that point it's trivial to apply styling to a ListBox control so that it shows up as a RadioButton list.

<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>

这篇关于MVVM:将单选按钮绑定到视图模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆