【问题标题】:Selecting an already selected RadioButton will select all RadioButtons选择已选择的单选按钮将选择所有单选按钮
【发布时间】:2022-02-01 18:43:25
【问题描述】:

我有两个单选按钮并将它们绑定到一个枚举 喜欢How to bind RadioButtons to an enum?

namespace RadioButtons
{
    public enum WorkModeEnum
    {
        Auto,
        Manual,
    }
}
<Window
    x:Class="RadioButtons.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:RadioButtons"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="800"
    Height="450"
    ContentRendered="Window_ContentRendered"
    mc:Ignorable="d">
    <Grid>
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <StackPanel.Resources>
                <local:EnumToBooleanConverter x:Key="ComparisonConverter" />
            </StackPanel.Resources>
            <RadioButton Content="Auto" IsChecked="{Binding Path=WorkMode, Mode=TwoWay, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static local:WorkModeEnum.Auto}}" />
            <RadioButton Content="Manual" IsChecked="{Binding Path=WorkMode, Mode=TwoWay, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static local:WorkModeEnum.Manual}}" />
        </StackPanel>
    </Grid>
</Window>

后面的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace RadioButtons
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ViewModel _vm;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_ContentRendered(object sender, EventArgs e)
        {
            _vm = new ViewModel();
            DataContext = _vm;
        }
    }
}

转换器代码如下所示

public class EnumToBooleanConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return ((Enum)value).HasFlag((Enum)parameter);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value.Equals(true) ? parameter : Binding.DoNothing;
        }
    }

视图模型

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace RadioButtons
{
    public class ViewModel : INotifyPropertyChanged
    {
        public ViewModel()
        {
            WorkMode = WorkModeEnum.Manual;
        }

        private WorkModeEnum _WorkMode;

        public WorkModeEnum WorkMode
        {
            get { return _WorkMode; }
            set
            {
                _WorkMode = value;
                NotifyPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

它可以工作,除了当用户点击手动按钮时,它已经被选中! 然后两个按钮都将显示为选中状态!

为什么以及如何解决它?

整个项目都可以访问(希望我以前从未这样做过)

https://github.com/Andis59/RadioButtons

【问题讨论】:

    标签: wpf enums binding radio-button


    【解决方案1】:

    您的问题是转换器。您使用的是普通枚举,但转换器将其视为[Flags](这是一种不同的)。

    如果给定标志的序数值是0,Enum.HasFlag(flag) 将始终返回true。您的 WorkModeEnum.Auto 具有 0 的序数值并导致此问题。

    您可以通过将 WorkModeEnum 定义更改为来解决此问题

    public enum WorkModeEnum
    {
        Auto = 1,
        Manual = 2,
    }
    

    但最好修复转换器

    public class EnumToBooleanConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return ((Enum)parameter).Equals((Enum)value);
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value.Equals(true) ? parameter : Binding.DoNothing;
        }
    }
    

    【讨论】:

    猜你喜欢
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多