WinForms RadioButtonList 不存在?

Posted

技术标签:

【中文标题】WinForms RadioButtonList 不存在?【英文标题】:WinForms RadioButtonList doesn't exist? 【发布时间】:2010-11-04 03:56:44 【问题描述】:

我知道WebForms 有一个RadioButtonList 控件,但我找不到WinForms 的控件。我需要将 3 个 RadioButtons 组合在一起,以便一次只能选择 1 个。我发现我必须通过代码来做到这一点,这很痛苦。我只是没有在某处看到RadioButtonList,还是WinForms 中真的不存在?

【问题讨论】:

【参考方案1】:

如果你只是想对单选按钮进行分组,将它们放在一个容器中就足够了,那么它们将像一个组一样工作,但是如果你需要像 ComboBoxListBoxCheckedListBox 这样的数据绑定有效,您需要一个RadioButtonList 控件。

Windows 窗体没有内置的RadioButtonList 控件。您可以通过派生表单ListBox 并使其所有者绘制并自己绘制单选按钮来创建自己的控件。这也是创建CheckedListBox 的方式。

这样,控件支持数据绑定,并受益于ListBox的所有功能,包括DataSourceSelectedValueDisplayMemberValueMember等。例如,您可以这样简单地使用它:

this.radioButtonList1.DataSource = peopleTable; 
this.radioButtonList1.DisplayMember = "Name"; 
this.radioButtonList1.ValueMember= "Id";

或者例如enum,就是这样:

this.radioButtonList1.DataSource = Enum.GetValues(typeof(DayOfWeek)); 

在下图中,第二个RadioButtonList 通过设置Enabled = false; 被禁用:

该控件也支持从右到左:

它还支持多列:

单选按钮列表

这里是控制的源代码。您可以像普通的ListBox 一样使用它,通过添加项目或设置数据源(有/没有使用数据绑定):

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
public class RadioButtonList : ListBox

    Size s;
    public RadioButtonList()
    
        this.DrawMode = DrawMode.OwnerDrawFixed;
        using (var g = Graphics.FromHwnd(IntPtr.Zero))
            s = RadioButtonRenderer.GetGlyphSize(
                Graphics.FromHwnd(IntPtr.Zero), RadioButtonState.CheckedNormal);
    
    protected override void OnDrawItem(DrawItemEventArgs e)
    

        var text = (Items.Count > 0) ? GetItemText(Items[e.Index]) : Name;
        Rectangle r = e.Bounds; Point p;
        var flags = TextFormatFlags.Default | TextFormatFlags.NoPrefix;
        var selected = (e.State & DrawItemState.Selected) == DrawItemState.Selected;
        var state = selected ?
            (Enabled ? RadioButtonState.CheckedNormal : 
                       RadioButtonState.CheckedDisabled) :
            (Enabled ? RadioButtonState.UncheckedNormal : 
                       RadioButtonState.UncheckedDisabled);
        if (RightToLeft == System.Windows.Forms.RightToLeft.Yes)
        
            p = new Point(r.Right - r.Height + (ItemHeight - s.Width) / 2,
                r.Top + (ItemHeight - s.Height) / 2);
            r = new Rectangle(r.Left, r.Top, r.Width - r.Height, r.Height);
            flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
        
        else
        
            p = new Point(r.Left + (ItemHeight - s.Width) / 2,
            r.Top + (ItemHeight - s.Height) / 2);
            r = new Rectangle(r.Left + r.Height, r.Top, r.Width - r.Height, r.Height);
        
        var bc = selected ? (Enabled ? SystemColors.Highlight : 
            SystemColors.InactiveBorder) : BackColor;
        var fc = selected ? (Enabled ? SystemColors.HighlightText : 
            SystemColors.GrayText) : ForeColor;
        using (var b = new SolidBrush(bc))
            e.Graphics.FillRectangle(b, e.Bounds);
        RadioButtonRenderer.DrawRadioButton(e.Graphics, p, state);
        TextRenderer.DrawText(e.Graphics, text, Font, r, fc, bc, flags);
        e.DrawFocusRectangle();
        base.OnDrawItem(e);
    
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public override SelectionMode SelectionMode
    
        get  return System.Windows.Forms.SelectionMode.One; 
        set  
    
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public override int ItemHeight
    
        get  return (this.Font.Height + 2); 
        set  
    
    [EditorBrowsable(EditorBrowsableState.Never), Browsable(false),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public override DrawMode DrawMode
    
        get  return base.DrawMode; 
        set  base.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; 
    

【讨论】:

【参考方案2】:

Apparently not.

您可以使用 GroupBox 或 Panel as is done here 将三个 RadioButton 组合在一起。

【讨论】:

很奇怪,我将它们分组在一个 GroupBox 中,但我认为它不起作用。谢谢! 是的,但是您失去了 RadioButtonList Value 属性的功能以及它的数据绑定潜力。【参考方案3】:

多个单选按钮位于同一个容器中这一简单事实使它们相互排斥,您不必自己编写此行为的代码。只需按照 Matthew 的建议将它们放在 Panel 或 GroupBox 中

【讨论】:

以上是关于WinForms RadioButtonList 不存在?的主要内容,如果未能解决你的问题,请参考以下文章

RadioButtonList

将 Bootstrap 样式应用于 RadioButtonList

查看 RadioButtonList 是不是具有选定值的最佳方法是啥?

强类型 RadioButtonlist

如何告诉 RadioButtonList 不生成表格

如何确定 JavaScript 中 RadioButtonList 的 SelectedValue?