在 C# 中使用不同的父控件对 Windows 窗体单选按钮进行分组

Posted

技术标签:

【中文标题】在 C# 中使用不同的父控件对 Windows 窗体单选按钮进行分组【英文标题】:Grouping Windows Forms Radiobuttons with different parent controls in C# 【发布时间】:2011-06-05 08:48:29 【问题描述】:

我有一个 Windows 窗体应用程序,其中有许多单选按钮。这些 RadioButtons 放置在 FlowLayoutPanel 中,它会自动为我安排它们。直接添加到 FlowLayoutPanel 的所有 RadioButton 都被分组,这意味着我只能选择其中一个。但是,其中一些 RadioButtons 与 TextBox 配对,因此我可以在那里提供一些参数。但是为了妥善安排这一切,我在 FlowLayoutPanel 中添加了一个 Panel 控件,这样我就可以自己控制 RadioButton 和 TextBox 相对于彼此的对齐方式。

这些 RadioButton 现在有自己的面板作为父控件,因此不再与其他 RadioButton 一起包含在单选组中。我读到 System.Web.UI 命名空间中的 RadioButtons 具有 GroupName 属性,但不幸的是,它们的 System.Windows.Forms 对应项缺少此属性。还有其他方法可以对这些单选按钮进行分组吗?我必须自己处理 onClick 事件吗?

谢谢, 杰瑞

【问题讨论】:

通常我们会使用分组框来分组单选按钮.. 【参考方案1】:

恐怕您将不得不手动处理...实际上还不错,您可能只需将所有 RadioButton 存储在一个列表中,并为所有这些使用单个事件处理程序:

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;
        
    

【讨论】:

我担心会是这样。不过应该问题不大。感谢您的帮助。 修复:rb.Checked = false; => other.Checked = false; @maxirby,我不明白你的评论......你是什么意思?【参考方案2】:

我同意@JonH - 使用标签是最干净的方法(恕我直言)

  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;
  

【讨论】:

【参考方案3】:

与第一个答案相比,这里有一点改进:创建一个 RadioGroup 类,该类封装了分组功能并添加了对标准键盘导航(向上/向下键)的支持,并使选项卡工作。

要使用它,只需在表单中声明一个 RadioGroup 成员并新建它(在 InitializeComponent() 之后),并以正确的顺序在组中传递您想要的所有单选按钮。

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;
                
            
        
    

一个警告:向上/向下键不能很好地与现有的 RadioButton 类一起使用,因为它已经处理了向上/向下键。将其修复为 RadioButton 的子类并关闭对上/下键的处理的一种简单方法:

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

【讨论】:

【参考方案4】:

@Jerry,我对 Windows 窗体不太熟悉,但我会试一试。如果有一个名为 Tag 的属性,您可以使用唯一的标签标记每个单选按钮。

【讨论】:

以上是关于在 C# 中使用不同的父控件对 Windows 窗体单选按钮进行分组的主要内容,如果未能解决你的问题,请参考以下文章

C# webBrowser控件禁用alert,confirm之类的弹窗解决方案

控制 C# windows 窗体的大小问题,在编译时看起来不同,在运行时看起来不同

C#在不同线程的同一类中的父线程中调用方法

C#获取当前窗体句柄及该窗体里的信息

C#中Windows设计窗怎么实现单选框和省市下拉框联动?

c#获取窗口句柄后 如何遍历所有控件