Grouping Windows Forms Radiobuttons with different parent controls in C#

前端 未结 4 1038
再見小時候
再見小時候 2021-01-11 19:30

I\'ve got a Windows Forms application in which I have a number of RadioButtons. These RadioButtons are placed within a FlowLayoutPanel which automatically arranges

相关标签:
4条回答
  • 2021-01-11 20:16

    Here is a little improvement over the first answer: create a RadioGroup class that encapsulates the grouping functionality and adds support for standard keyboard navigation (up/down keys) and makes tabbing work.

    To use it, simply declare a RadioGroup member in your form and new it (after InitializeComponent()), passing all the radio buttons you want in the group in proper order.

    public class RadioGroup
    {
        List<RadioButton> _radioButtons;
    
        public RadioGroup(params RadioButton[] radioButtons)
        {
            _radioButtons = new List<RadioButton>(radioButtons);
            foreach (RadioButton radioButton in _radioButtons)
            {
                radioButton.TabStop = false;
                radioButton.KeyUp += new KeyEventHandler(radioButton_KeyUp);
                radioButton.CheckedChanged += new EventHandler(radioButton_CheckedChanged);
            }
            _radioButtons[0].TabStop = true;
        }
    
        void radioButton_KeyUp(object sender, KeyEventArgs e)
        {
            e.Handled = true;
            RadioButton radioButton = (RadioButton)sender;
            int index = _radioButtons.IndexOf(radioButton);
    
            if (e.KeyCode == Keys.Down)
            {
                index++;
                if (index >= _radioButtons.Count)
                {
                    index = 0;
                }
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.Up)
            {
                index--;
                if (index < 0)
                {
                    index = _radioButtons.Count - 1;
                }
                e.Handled = true;
            }
    
            radioButton = _radioButtons[index];
            radioButton.Focus();
            radioButton.Select();
        }
    
        void radioButton_CheckedChanged(object sender, EventArgs e)
        {
            RadioButton currentRadioButton = (RadioButton)sender;
    
            if (currentRadioButton.Checked)
            {
                foreach (RadioButton radioButton in _radioButtons)
                {
                    if (!radioButton.Equals(currentRadioButton))
                    {
                        radioButton.Checked = false;
                    }
                }
            }
        }
    }
    

    One caveat: the up/down keys won't work well with the existing RadioButton class because it already handles the up/down keys. One easy way to fix it to subclass RadioButton and turn off handling of up/down keys:

    public class RadioButtonEx : RadioButton
    {
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Up || keyData == Keys.Down)
            {
                return true;
            }
    
            return base.ProcessCmdKey(ref msg, keyData);
        }
    }
    
    0 讨论(0)
  • 2021-01-11 20:19

    I'm afraid you'll have to handle this manually... It's not so bad actually, you can probably just store all the RadioButton in a list, and use a single event handler for all of them:

    private List<RadioButton> _radioButtonGroup = new List<RadioButton>();
    private void radioButton_CheckedChanged(object sender, EventArgs e)
    {
        RadioButton rb = (RadioButton)sender;
        if (rb.Checked)
        {
            foreach(RadioButton other in _radioButtonGroup)
            {
                if (other == rb)
                {
                    continue;
                }
                other.Checked = false;
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-11 20:25

    I agree with @JonH - using tags is the cleanest way to do that (imho)

      private void FormLoad(object sender, EventArgs e)
      {
         radioCsv.Tag = DataTargetTypes.CsvFile;
         radioTabbed.Tag = DataTargetTypes.TxtFile;
         radioSas.Tag = DataTargetTypes.SasFile;
      }
    
      private void RadioButtonCheckedChanged(object sender, EventArgs e)
      {
         var radio = (RadioButton) sender;
         this.DataDestinationType = (DataTargetTypes)radio.Tag;
      }
    
    0 讨论(0)
  • 2021-01-11 20:26

    @Jerry, I'm not too familiar with Windows Forms, but I will take a shot. If there a property called Tag, you could tag each radio button with a unique tag.

    0 讨论(0)
提交回复
热议问题