在WinForms中,绑定一组单选按钮的最佳方法是什么?

26

我目前正在将我的现有Windows Forms进行数据绑定,但是我在确定如何正确地对GroupBox中的一组RadioButton控件进行数据绑定时遇到了问题。

我的业务对象具有一个整数属性,我想将其与4个RadioButton(其中每个都表示值0-3)进行数据绑定。

当前,我正在绑定一个Presenter对象来充当表单和业务对象之间的绑定器。我现在所做的方式是拥有4个单独的属性,其中每个属性都绑定到这些值中的一个(我使用INotifyPropertyChanged,但此处不包括它):

Private int _propValue;

Public bool PropIsValue0 
{ 
  get { return _propValue == 0; }
  set
  {
    if (value) 
      _propValue = 0;
  }
}

Public bool PropIsValue1 { // As above, but with value == 1 }
Public bool PropIsValue2 { // As above, but with value == 2 }
Public bool PropIsValue3 { // As above, but with value == 3 }

然后我像上面那样将每个单选按钮绑定到它们各自的属性。

这种做法对我来说似乎不太对,所以非常感谢任何建议。

10个回答

27

以下是一个通用的RadioGroupBox实现,灵感来自ArielBH的建议(部分代码借鉴于Jay Andrew Allen的RadioPanel)。只需添加RadioButton控件,将它们的标签设置为不同的整数并绑定到“Selected”属性即可。

public class RadioGroupBox : GroupBox
{
    public event EventHandler SelectedChanged = delegate { };

    int _selected;
    public int Selected
    {
        get
        {
            return _selected;
        }
        set
        {
            int val = 0;
            var radioButton = this.Controls.OfType<RadioButton>()
                .FirstOrDefault(radio =>
                    radio.Tag != null 
                   && int.TryParse(radio.Tag.ToString(), out val) && val == value);

            if (radioButton != null)
            {
                radioButton.Checked = true;
                _selected = val;
            }
        }
    }

    protected override void OnControlAdded(ControlEventArgs e)
    {
        base.OnControlAdded(e);

        var radioButton = e.Control as RadioButton;
        if (radioButton != null)
            radioButton.CheckedChanged += radioButton_CheckedChanged;
    }

    void radioButton_CheckedChanged(object sender, EventArgs e)
    {
        var radio = (RadioButton)sender;
        int val = 0;
        if (radio.Checked && radio.Tag != null 
             && int.TryParse(radio.Tag.ToString(), out val))
        {
            _selected = val;
            SelectedChanged(this, new EventArgs());
        }
    }
}

请注意,由于在InitializeComponent中存在初始化顺序问题(绑定操作在单选按钮初始化之前执行,因此它们的标记在第一次分配时为null),因此您无法通过设计器绑定到'Selected'属性。所以只需像下面这样自己进行绑定:

    public Form1()
    {
        InitializeComponent();
        //Assuming selected1 and selected2 are defined as integer application settings
        radioGroup1.DataBindings.Add("Selected", Properties.Settings.Default, "selected1");
        radioGroup2.DataBindings.Add("Selected", Properties.Settings.Default, "selected2");
    }

太棒了,谢谢!反正我也不是通过设计师来绑定,所以这很完美。我正在使用StrongBind(http://code.google.com/p/strongbind/)来绑定我的控件。 - Geir-Tore Lindsve
很高兴能提供帮助 :) 谢谢您的提示,我会查看StrongBind,看起来很有趣。 - Ohad Schneider

6

我知道这篇帖子很旧,但在寻找解决同样问题的答案时,我看到了这篇帖子,但它没有解决我的问题。刚刚一分钟前我突然想到一个办法,想分享一下我的解决方案。

我有一个组合框里面有三个单选按钮。我使用一个自定义类对象的 List<> 作为数据源。

自定义类对象:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BAL
{
class ProductItem
{

    // Global Variable to store the value of which radio button should be checked
    private int glbTaxStatus;
    // Public variable to set initial value passed from 
    // database query and get value to save to database
    public int TaxStatus
    {
        get { return glbTaxStatus; }
        set { glbTaxStatus = value; }
    }

    // Get/Set for 1st Radio button
    public bool Resale
    {
        // If the Global Variable = 1 return true, else return false
        get
        {
            if (glbTaxStatus.Equals(1))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        // If the value being passed in = 1 set the Global Variable = 1, else do nothing
        set
        {
            if (value.Equals(true))
            {
                glbTaxStatus = 1;
            }
        }
    }

    // Get/Set for 2nd Radio button
    public bool NeverTax
    {
        // If the Global Variable = 2 return true, else return false
        get
        {
            if (glbTaxStatus.Equals(2))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        // If the value being passed in = 2 set the Global Variable = 2, else do nothing
        set
        {
            if (value.Equals(true))
            {
                glbTaxStatus = 2;
            }
        }
    }

    // Get/Set for 3rd Radio button
    public bool AlwaysTax
    {
        // If the Global Variable = 3 return true, else return false
        get
        {
            if (glbTaxStatus.Equals(3))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        // If the value being passed in = 3 set the Global Variable = 3, else do nothing
        set
        {
            if (value.Equals(true))
            {
                glbTaxStatus = 3;
            }
        }
    }

// More code ...

有三个单独的公共变量,通过get/set访问同一个全局变量。

在代码后台中,我有一个函数在Page_Load()期间被调用,设置所有控件的数据绑定。对于每个单选按钮,我都添加了自己的数据绑定。

radResale.DataBindings.Add("Checked", glbProductList, "Resale", true, DataSourceUpdateMode.OnPropertyChanged, false);
radNeverTax.DataBindings.Add("Checked", glbProductList, "NeverTax", true, DataSourceUpdateMode.OnPropertyChanged, false);
radAlwaysTax.DataBindings.Add("Checked", glbProductList, "Always", true, DataSourceUpdateMode.OnPropertyChanged, false);

我希望这能对某些人有所帮助!

1
谢谢@paul - 在使用您的绑定选项之前,我看到了非常奇怪的行为(点击按钮C,属性B的setter被赋值为true),但现在一切都好了。显然,这需要同时设置formattingEnabled=true和nullValue=false参数才能正常工作。虽然不知道原因,但它确实有效,所以我50%满意! - Jon
是的,这很有帮助,因为我永远不会猜到 formattingEnabled 参数需要是“true”,而 nullValue 参数需要是“false”。在 RadioButton 上?!无论如何,它起作用了。谢谢。 - B H

2

我认为我会使用自己的GroupBox。我会将CustomGroupBox绑定到你的模型上,并根据绑定的值设置正确的RadioButton(使用标签或名称属性)。


听起来好多了。谢谢你的提示。 - Geir-Tore Lindsve

1
这是我绑定枚举列表到单选按钮的方法。
在按钮的Tag属性中使用枚举作为字符串,我使用Binding.Format和Binding.Parse事件来决定哪个按钮应该被选中。
public enum OptionEnum
{
   Option1 = 0,
   Option2
}

OptionEnum _rbEnum = OptionEnum.Option1;
OptionEnum PropertyRBEnum
{
    get { return _rbEnum; }
    set
    {
        _rbEnum = value;
        RaisePropertyChanged("PropertyRBEnum");
    }
}

public static void FormatSelectedEnum<T>(object sender, ConvertEventArgs args) where T : struct
{
    Binding binding = (sender as Binding);
    if (binding == null) return;

    Control button = binding.Control;

    if (button == null || args.DesiredType != typeof(Boolean)) return;

    T value = (T)args.Value;
    T controlValue;

    if (Enum.TryParse(button.Tag.ToString(), out controlValue))
    {
        args.Value = value.Equals(controlValue);
    }
    else
    {
        Exception ex = new Exception("String not found in Enum");
        ex.Data.Add("Tag", button.Tag);

        throw ex;
    }
}

public static void ParseSelectedEnum<T>(object sender, ConvertEventArgs args) where T : struct
{
    Binding binding = (sender as Binding);
    if (binding == null) return;

    Control button = binding.Control;
    bool value = (bool)args.Value;

    if (button == null || value != true) return;

    T controlValue;

    if (Enum.TryParse(button.Tag.ToString(), out controlValue))
    {
        args.Value = controlValue;
    }
    else
    {
        Exception ex = new Exception("String not found in Enum");
        ex.Data.Add("Tag", button.Tag);

        throw ex;
    }
}

然后像这样设置您的数据绑定:

radioButton1.Tag = "Option1";
radioButton2.Tag = "Option2";

foreach (RadioButtonUx rb in new RadioButtonUx[] { radioButton1, radioButton2 })
{
    Binding b = new Binding("Checked", this, "PropertyRBEnum");
    b.Format += FormatSelectedRadioButton<OptionEnum>;
    b.Parse += ParseSelectedRadioButton<OptionEnum>;

    rb.DataBindings.Add(b);
}

0
我想就代码块提出一些观察,这可能对阅读这些帖子的人有所帮助。由于其结构,以下代码可能并不总是按预期工作。
try
    {
      val = System.Enum.Parse(this.enumType, rb.Text) as System.Enum;
    }
    catch(Exception ex)
    {
      // cannot occurred if code is safe
      System.Windows.Forms.MessageBox.Show("No enum value for this radio button : " + ex.ToString());
    }
    object obj = this.bindingSource.Current;
    obj.GetType().GetProperty(propertyName).SetValue(obj, val, new object[] {
    }
  );
  this.bindingSource.CurrencyManager.Refresh();

如果 try 块中发生错误,将执行 catch 块。在 catch 块后,代码将继续执行。由于没有处理绑定源,catch 后面的变量可能处于不确定状态,并可能引发另一个异常,该异常可能已经处理或未处理。
更好的方法如下:
 try
        {
            val = System.Enum.Parse(this.enumType, rb.Text) as System.Enum;

        object obj = this.bindingSource.Current;
        obj.GetType().GetProperty(propertyName).SetValue(obj, val, new object[] { });
        this.bindingSource.CurrencyManager.Refresh();
        }
        catch(EntityException ex)
        {
            // handle error
        }
        catch(Exception ex)
        {
            // cannot occurred if code is safe
            System.Windows.Forms.MessageBox.Show("No enum value for this radio button : " + ex.ToString());
        }

这样可以处理枚举值错误以及其他可能发生的错误。但是在 Exception 块之前使用 EntityException 或其变体(所有 Exception 的后代必须首先出现)。可以使用实体框架类而不是 Exception 基类获取特定实体状态信息,以处理实体框架错误。这对于调试或为用户提供更清晰的运行时消息非常有帮助。

当我设置 try-catch 块时,我喜欢将其视为代码上方的“层”。我决定异常在程序中的流动、它们向用户的显示以及任何清理工作,以使程序能够继续正常工作,而不会产生不确定状态的对象,从而导致其他错误。


0

我喜欢Jan Hoogma的GroupBox绑定,但更喜欢可以绑定的值的更多控制权,因此创建了RadioButtonBIndable,可以将不同类型的值分配给它,这些值是强类型的。

public class RadioButtonBindable : RadioButton
{
    public Int32 ValueInt { get; set; }   
    public Decimal ValueDecimal { get; set; }
    public String ValueString { get; set; }
    public Boolean ValueBoolean { get; set; }
}

接着我可以处理GroupBox并创建GroupBoxBindable,它可以绑定到RadioButtonBindable中的任何值(您可以绑定多个值,例如ValueInt = 23和ValueString =“示例文本”)。在没有选中单选按钮的不太可能事件发生时,您还可以设置默认值。

public class RadioButtonGroupBoxBindable : GroupBox, INotifyPropertyChanged
{
    //public event EventHandler SelectedChanged = delegate { };
    public event EventHandler ValueIntChanged = delegate { };
    public event EventHandler ValueDecimalChanged = delegate { };
    public event EventHandler ValueStringChanged = delegate { };
    public event EventHandler ValueBooleanChanged = delegate { };
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    public Int32 DefaultValueInt { get; set; }
    public Decimal DefaultValueDecimal { get; set; }
    public String DefaultValueString { get; set; }
    public Boolean DefaultValueBoolean { get; set; }
    public Boolean ValueBoolean
    {
        set
        {
            foreach (Control control in this.Controls)
            {
                if (control is RadioButtonBindable)
                {
                    RadioButtonBindable item = (RadioButtonBindable)control;
                    if (item.ValueBoolean == value)
                    {
                        item.Checked = true;
                        break;
                    }
                }
            }
        }
        get
        {
            Boolean retVal = DefaultValueBoolean;
            foreach (Control control in this.Controls)
            {
                if (control is RadioButtonBindable)
                {
                    RadioButtonBindable item = (RadioButtonBindable)control;
                    if (item.Checked)
                    {
                        retVal = item.ValueBoolean;
                        break;
                    }
                }
            }
            return retVal;
        }
    }
    public int ValueInt
    {
        set
        {
            foreach (Control control in this.Controls)
            {
                if (control is RadioButtonBindable)
                {
                    RadioButtonBindable item = (RadioButtonBindable)control;
                    if (item.ValueInt == value)
                    {
                        item.Checked = true;
                        break;
                    }
                }
            }
        }
        get
        {
            int retVal = DefaultValueInt;
            foreach (Control control in this.Controls)
            {
                if (control is RadioButtonBindable)
                {
                    RadioButtonBindable item = (RadioButtonBindable)control;
                    if (item.Checked)
                    {
                        retVal = item.ValueInt;
                        break;
                    }
                }
            }
            return retVal;
        }
    }
    public decimal ValueDecimal
    {
        set
        {
            foreach (Control control in this.Controls)
            {
                if (control is RadioButtonBindable)
                {
                    RadioButtonBindable item = (RadioButtonBindable)control;
                    if (item.ValueDecimal == value)
                    {
                        item.Checked = true;
                        break;
                    }
                }
            }
        }
        get
        {
            decimal retVal = DefaultValueDecimal;
            foreach (Control control in this.Controls)
            {
                if (control is RadioButtonBindable)
                {
                    RadioButtonBindable item = (RadioButtonBindable)control;
                    if (item.Checked)
                    {
                        retVal = item.ValueDecimal;
                        break;
                    }
                }
            }
            return retVal;
        }
    }
    public string ValueString
    {
        set
        {
            foreach (Control control in this.Controls)
            {
                if (control is RadioButtonBindable)
                {
                    RadioButtonBindable item = (RadioButtonBindable)control;
                    if (item.ValueString == value)
                    {
                        item.Checked = true;
                        break;
                    }
                }
            }
        }
        get
        {
            string retVal = DefaultValueString;
            foreach (Control control in this.Controls)
            {
                if (control is RadioButtonBindable)
                {
                    RadioButtonBindable item = (RadioButtonBindable)control;
                    if (item.Checked)
                    {
                        retVal = item.ValueString;
                        break;
                    }
                }
            }
            return retVal;
        }
    }
    protected override void OnControlAdded(ControlEventArgs e)
    {
        base.OnControlAdded(e);

        var radioButton = e.Control as RadioButtonBindable;
        if (radioButton != null)
            radioButton.CheckedChanged += radioButton_CheckedChanged;
    }
    void radioButton_CheckedChanged(object sender, EventArgs e)
    {
        if (((RadioButtonBindable)sender).Checked)
        {
            OnPropertyChanged("ValueInt");
            OnPropertyChanged("ValueDecimal");
            OnPropertyChanged("ValueString");
            OnPropertyChanged("ValueBoolean");
            ValueIntChanged(this, new EventArgs());
            ValueDecimalChanged(this, new EventArgs());
            ValueStringChanged(this, new EventArgs());
            ValueBooleanChanged(this, new EventArgs());
        }
    }
}

0

我开始解决同样的问题。

我使用了一个RadioButtonBinding类,该类封装了数据源中有关枚举的所有单选按钮。

以下类将所有单选按钮保存在列表中,并对枚举进行查找:

class RadioButtonBinding : ILookup<System.Enum, System.Windows.Forms.RadioButton>
{
    private Type enumType;
    private List<System.Windows.Forms.RadioButton> radioButtons;
    private System.Windows.Forms.BindingSource bindingSource;
    private string propertyName;

    public RadioButtonBinding(Type myEnum, System.Windows.Forms.BindingSource bs, string propertyName)
    {
        this.enumType = myEnum;
        this.radioButtons = new List<System.Windows.Forms.RadioButton>();
        foreach (string name in System.Enum.GetNames(this.enumType))
        {
            System.Windows.Forms.RadioButton rb = new System.Windows.Forms.RadioButton();
            rb.Text = name;
            this.radioButtons.Add(rb);
            rb.CheckedChanged += new EventHandler(rb_CheckedChanged);
        }
        this.bindingSource = bs;
        this.propertyName = propertyName;
        this.bindingSource.DataSourceChanged += new EventHandler(bindingSource_DataSourceChanged);
    }

    void bindingSource_DataSourceChanged(object sender, EventArgs e)
    {
        object obj = this.bindingSource.Current;
        System.Enum item = obj.GetType().GetProperty(propertyName).GetValue(obj, new object[] { }) as System.Enum;
        foreach (System.Enum value in System.Enum.GetValues(this.enumType))
        {
            if (this.Contains(value))
            {
                System.Windows.Forms.RadioButton rb = this[value].First();
                if (value.Equals(item))
                {
                    rb.Checked = true;
                }
                else
                {
                    rb.Checked = false;
                }
            }
        }
    }

    void rb_CheckedChanged(object sender, EventArgs e)
    {
        System.Windows.Forms.RadioButton rb = sender as System.Windows.Forms.RadioButton;
        System.Enum val = null;
        try
        {
            val = System.Enum.Parse(this.enumType, rb.Text) as System.Enum;
        }
        catch(Exception ex)
        {
            // cannot occurred if code is safe
            System.Windows.Forms.MessageBox.Show("No enum value for this radio button : " + ex.ToString());
        }
        object obj = this.bindingSource.Current;
        obj.GetType().GetProperty(propertyName).SetValue(obj, val, new object[] { });
        this.bindingSource.CurrencyManager.Refresh();
    }

    public int Count
    {
        get
        {
            return System.Enum.GetNames(this.enumType).Count();
        }
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.radioButtons.GetEnumerator();
    }

    public bool Contains(Enum key)
    {
        return System.Enum.GetNames(this.enumType).Contains(key.ToString());
    }

    public IEnumerable<System.Windows.Forms.RadioButton> this[Enum key]
    {
        get
        {
            return this.radioButtons.FindAll(a => { return a.Text == key.ToString(); });
        }
    }

    IEnumerator<IGrouping<Enum, System.Windows.Forms.RadioButton>> IEnumerable<IGrouping<Enum, System.Windows.Forms.RadioButton>>.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    public void AddControlsIntoGroupBox(System.Windows.Forms.GroupBox gb)
    {
        System.Windows.Forms.FlowLayoutPanel panel = new System.Windows.Forms.FlowLayoutPanel();
        panel.Dock = System.Windows.Forms.DockStyle.Fill;
        panel.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft;
        foreach (System.Windows.Forms.RadioButton rb in this.radioButtons)
        {
            panel.Controls.Add(rb);
        }
        gb.Controls.Add(panel);
    }
}

您可以通过在表单的构造函数中添加该代码,将该类用于表单:

    public PageView()
    {
        InitializeComponent();
        RadioButtonBinding rbWidth = new RadioButtonBinding(typeof(Library.EnumConstraint), this.pageBindingSource, "ConstraintWidth");
        rbWidth.AddControlsIntoGroupBox(this.groupBox1);
        RadioButtonBinding rbHeight = new RadioButtonBinding(typeof(Library.EnumConstraint), this.pageBindingSource, "ConstraintHeight");
        rbHeight.AddControlsIntoGroupBox(this.groupBox3);
        this.pageBindingSource.CurrentItemChanged += new EventHandler(pageBindingSource_CurrentItemChanged);
    }

0

将单选按钮的标签名称设置为代表该值的内容。

创建一个字符串设置,例如OptionDuplicateFiles,并将其默认值设置为默认单选按钮的标签名称。

要保存所选的单选按钮:

Settings.Default.OptionDuplicateFiles = gbxDuplicateFiles.Controls
   .OfType<RadioButton>()
   .Where(b => b.Checked)
   .Select(b => b.Tag)
   .First()
   .ToString();

加载已选中的单选按钮:

(gbxDuplicateFiles.Controls
   .OfType<RadioButton>()
   .Where(b => b.Tag.ToString() == Settings.Default.OptionDuplicateFiles)
   .First())
   .Checked = true;

完成了!


0

我喜欢RadioButtonGroupBox的想法,但我决定创建一个自支持的版本。 没有理由为Tag属性添加值或引入新的值属性。 任何分配的单选按钮仍然是RadioButtonGroupBox的成员,并且单选按钮的顺序在开发期间定义。 所以,我修改了代码。 现在,我可以通过索引位置、控件名称和文本获取和设置所选的单选按钮。 顺便说一句,如果您为每个单选按钮分配的文本不同,则只能使用文本。

public class RadioButtonGroupBox : GroupBox
{
    public event EventHandler SelectedChanged = delegate { };

    int _nIndexPosCheckRadioButton = -1;
    int _selected;
    public int Selected
    {
        get
        {
            return _selected;
        }
    }


    public int CheckedRadioButtonIndexPos
    {
        set
        {
            int nPosInList = -1;
            foreach (RadioButton item in this.Controls.OfType<RadioButton>())
            {
                // There are RadioButtonItems in the list...
                nPosInList++;

                // Set the RB that should be checked
                if (nPosInList == value)
                {
                    item.Checked = true;
                    // We can stop with the loop
                    break;
                }
            }
            _nIndexPosCheckRadioButton = nPosInList;
        }
        get
        {
            int nPosInList = -1;
            int nPosCheckeItemInList = -1;

            foreach (RadioButton item in this.Controls.OfType<RadioButton>())
            {
                // There are RadioButtonItems in the list...
                nPosInList++;

                // Find the RB that is checked
                if (item.Checked)
                {
                    nPosCheckeItemInList = nPosInList;
                    // We can stop with the loop
                    break;
                }
            }
            _nIndexPosCheckRadioButton = nPosCheckeItemInList;
            return _nIndexPosCheckRadioButton;
        }
    }

    public string CheckedRadioButtonByText
    {
        set
        {
            int nPosInList = -1;
            foreach (RadioButton item in this.Controls.OfType<RadioButton>())
            {
                // There are RadioButtonItems in the list...
                nPosInList++;

                // Set the RB that should be checked
                if (item.Text == value)
                {
                    item.Checked = true;
                    // We can stop with the loop
                    break;
                }
            }
            _nIndexPosCheckRadioButton = nPosInList;
        }
        get
        {
            string cByTextValue = "__UNDEFINED__";
            int nPosInList = -1;
            int nPosCheckeItemInList = -1;

            foreach (RadioButton item in this.Controls.OfType<RadioButton>())
            {
                // There are RadioButtonItems in the list...
                nPosInList++;

                // Find the RB that is checked
                if (item.Checked)
                {
                    cByTextValue = item.Text;
                    nPosCheckeItemInList = nPosInList;
                    // We can stop with the loop
                    break;
                }
            }
            _nIndexPosCheckRadioButton = nPosCheckeItemInList;
            return cByTextValue;
        }
    }

    public string CheckedRadioButtonByName
    {
        set
        {
            int nPosInList = -1;
            foreach (RadioButton item in this.Controls.OfType<RadioButton>())
            {
                // There are RadioButtonItems in the list...
                nPosInList++;

                // Set the RB that should be checked
                if (item.Name == value)
                {
                    item.Checked = true;
                    // We can stop with the loop
                    break;
                }
            }
            _nIndexPosCheckRadioButton = nPosInList;
        }
        get
        {
            String cByNameValue = "__UNDEFINED__";
            int nPosInList = -1;
            int nPosCheckeItemInList = -1;

            foreach (RadioButton item in this.Controls.OfType<RadioButton>())
            {
                // There are RadioButtonItems in the list...
                nPosInList++;

                // Find the RB that is checked
                if (item.Checked)
                {
                    cByNameValue = item.Name;
                    nPosCheckeItemInList = nPosInList;
                    // We can stop with the loop
                    break;
                }
            }
            _nIndexPosCheckRadioButton = nPosCheckeItemInList;
            return cByNameValue;
        }
    }


    protected override void OnControlAdded(ControlEventArgs e)
    {
        base.OnControlAdded(e);

        var radioButton = e.Control as RadioButton;
        if (radioButton != null)
            radioButton.CheckedChanged += radioButton_CheckedChanged;
    }


    void radioButton_CheckedChanged(object sender, EventArgs e)
    {
        _selected = CheckedRadioButtonIndexPos;
        SelectedChanged(this, new EventArgs());
    }

}

0

我的方法是将每个单选按钮放入自己的面板中,然后再将它们绑定到一个布尔属性:

    public static Binding Bind<TObject>(this RadioButton control, object dataSource, string dataMember)
    {
        // Put the radio button into its own panel
        Panel panel = new Panel();
        control.Parent.Controls.Add(panel);
        panel.Location = control.Location;
        panel.Size = control.Size;
        panel.Controls.Add(control);
        control.Location = new Point(0, 0);

        // Do the actual data binding
        return control.DataBindings.Add("Checked", dataSource, dataMember);
    }

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