Winforms将枚举绑定到单选按钮

12

如果我有三个单选按钮,将它们与具有相同选项的枚举绑定的最佳方法是什么? 例如:

[] Choice 1
[] Choice 2
[] Choice 3

public enum MyChoices
{
    Choice1,
    Choice2,
    Choice3
}
4个回答

14

我知道这是一个老问题,但它是我搜索结果中第一个出现的。我找到了一种通用的方法来将单选按钮绑定到枚举,甚至是字符串或数字等。

    private void AddRadioCheckedBinding<T>(RadioButton radio, object dataSource, string dataMember, T trueValue)
    {
        var binding = new Binding(nameof(RadioButton.Checked), dataSource, dataMember, true, DataSourceUpdateMode.OnPropertyChanged);
        binding.Parse += (s, a) => { if ((bool)a.Value) a.Value = trueValue; };
        binding.Format += (s, a) => a.Value = ((T)a.Value).Equals(trueValue);
        radio.DataBindings.Add(binding);
    }

然后,要么在窗体的构造函数中,要么在窗体加载事件中,对每个 RadioButton 控件调用它。 dataSource 是包含您的枚举属性的对象。我确保 dataSource 实现了 INotifyPropertyChanged 接口,并在枚举属性的 setter 中触发了 OnPropertyChanged 事件。

AddRadioCheckedBinding(Choice1RadioButton, dataSource, "MyChoice", MyChoices.Choice1);
AddRadioCheckedBinding(Choice2RadioButton, dataSource, "MyChoice", MyChoices.Choice2);

2
哇,这真是救命之恩啊!我差点又创建了一个新的账户来点赞两次!当然,我已经将其转换为扩展方法了:public static void AddRadioCheckedBinding<T>(this RadioButton radio, object dataSource, string dataMember, T trueValue) - Marcelo Scofano Diniz

2

您能创建三个布尔属性吗:

private MyChoices myChoice;

public bool MyChoice_Choice1
{
    get { return myChoice == MyChoices.Choice1; }
    set { if (value) myChoice = MyChoices.Choice1; myChoiceChanged(); }
}

// and so on for the other two

private void myChoiceChanged()
{
    OnPropertyChanged(new PropertyChangedEventArgs("MyChoice_Choice1"));
    OnPropertyChanged(new PropertyChangedEventArgs("MyChoice_Choice2"));
    OnPropertyChanged(new PropertyChangedEventArgs("MyChoice_Choice3"));
}

然后绑定到MyChoice_Choice1和其他选项?

0
问题的提问者没有提到他正在绑定什么。我猜他是绑定到XXX.Properties.Settings类。如果不是这样,这个解决方案需要绑定类来实现 INotifyPropertyChanged 接口。
并且有一个像这样的索引器:
public object this[string propertyName] { get; set; }

我尝试了由WeskerTyrant提供的已接受的解决方案,但失败了。 在它起作用之前,我不得不点击两次。 所以我开始自己解决问题。我注意到我要绑定的类实现了INotifyPropertyChanged接口,该接口有一个名为PropertyChanged的PropertyChangedEventHandler。 (顺便说一下,我使用的是.net 472) 因此,我自己编写了一个帮助类。
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Windows.Forms;
namespace Ezfx.Dui
{
    public static class RadioButtonGroupUI
    {
        public static void Apply(ApplicationSettingsBase settings, string key, Control parentControl)
        {
            List<RadioButton> radios = new List<RadioButton>();
            foreach(Control control in parentControl.Controls)
            {
                switch (control)
                {
                    case RadioButton e:
                        radios.Add(e);
                        break;
                }
            }

            Apply(settings, key, radios.ToArray());
        }

        public static void Apply(ApplicationSettingsBase settings, string key, params RadioButton[] radios)
        {

            foreach (RadioButton radioButton in radios)
            {
                if (radioButton.Text == (string)settings[key])
                {
                    radioButton.Checked = true;
                }

                radioButton.CheckedChanged += (sender, e) => {
                    if (radioButton.Checked)
                    {
                        settings[key] = radioButton.Text;
                    }
                    
                };
            }

            settings.PropertyChanged += (sender, e) =>
            {
                foreach (RadioButton radioButton in radios)
                {
                    if (radioButton.Text == (string)settings[key])
                    {
                        radioButton.Checked = true;
                    }
                    else
                    {
                        radioButton.Checked = false;
                    }
                }
            };
        }
    }
}

使用它时,只需在form_load事件中添加以下代码。

    private void MainForm_Load(object sender, EventArgs e)
    {
        RadioButtonGroupUI.Apply(settings, "category", categoryGroupBox);
        RadioButtonGroupUI.Apply(settings, "package", scikitLearnRadioButton, sparkRadioButton);
    }

我在 Github 上分享了这个:

https://github.com/EricWebsmith/Ezfx.Dui

我猜人们会对我投反对票,因为这并没有回答关于枚举的问题。我的解决方案是在使用时将设置强制转换。在我的情况下,我在Python脚本中使用设置,所以不需要转换。

Enum.TryParse(settings.category, out Category category);

0

我只是想分享一下我目前的做法。虽然没有所谓的“绑定”,但希望它能够完成同样的工作。

欢迎评论。

public enum MyChoices
{
    Choice1,
    Choice2,
    Choice3
}

public partial class Form1 : Form
{
    private Dictionary<int, RadioButton> radButtons;
    private MyChoices choices;

    public Form1()
    {
        this.InitializeComponent();
        this.radButtons = new Dictionary<int, RadioButton>();
        this.radButtons.Add(0, this.radioButton1);
        this.radButtons.Add(1, this.radioButton2);
        this.radButtons.Add(2, this.radioButton3);

        foreach (var item in this.radButtons)
        {
            item.Value.CheckedChanged += new EventHandler(RadioButton_CheckedChanged);
        }
    }

    private void RadioButton_CheckedChanged(object sender, EventArgs e)
    {
        RadioButton button = sender as RadioButton;
        foreach (var item in this.radButtons)
        {
            if (item.Value == button)
            {
                this.choices = (MyChoices)item.Key;
            }
        }
    }

    public MyChoices Choices
    {
        get { return this.choices; }
        set
        {
            this.choices = value;
            this.SelectRadioButton(value);
            this.OnPropertyChanged(new PropertyChangedEventArgs("Choices"));
        }
    }

    private void SelectRadioButton(MyChoices choiceID)
    {
        RadioButton button;
        this.radButtons.TryGetValue((int)choiceID, out button);
        button.Checked = true;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接