【问题标题】:Winforms Bind Enum to Radio ButtonsWinforms 将枚举绑定到单选按钮
【发布时间】:2011-01-29 10:17:16
【问题描述】:

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

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

public enum MyChoices
{
    Choice1,
    Choice2,
    Choice3
}

【问题讨论】:

    标签: c# winforms data-binding enums radio-button


    【解决方案1】:

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

        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 接口在枚举属性设置器中触发OnPropertyChanged 事件。

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

    【讨论】:

    • 伙计,这是救命的!几乎试图创建另一个配置文件只是为了 UpVote 两次!当然,我将其转换为扩展方法:public static void AddRadioCheckedBinding&lt;T&gt;(this RadioButton radio, object dataSource, string dataMember, T trueValue)
    【解决方案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 和其他?

    【讨论】:

      【解决方案3】:

      我只是想我会添加我目前正在做的方式。没有这样的“绑定”,但希望它能起到同样的作用。

      欢迎评论。

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

      【讨论】:

        【解决方案4】:

        问题发布者没有提及他绑定的内容。我想他绑定到 XXX.Properties.Settings 类。如果没有,这个方案需要绑定类来实现INotifyPropertyChanged接口。

        并且有一个这样的索引器:

        public object this[string propertyName] { get; set; }
        

        我尝试了 WeskerTyrant 提供的公认解决方案,但失败了。

        我必须点击两次才能工作。

        于是我开始自己解决问题。我注意到我绑定的类实现了 INotifyPropertyChanged 接口。其中有一个名为 PropertyChangedPropertyChangedEventHandler

        (顺便说一下,我使用的是 .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);
        

        【讨论】:

          猜你喜欢
          • 2014-10-14
          • 1970-01-01
          • 2013-07-16
          • 1970-01-01
          • 2012-05-18
          • 2013-08-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多