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

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

【问题讨论】:

    标签: c# winforms radio-button radiobuttonlist


    【解决方案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 中

      【讨论】:

        猜你喜欢
        • 2010-09-08
        • 1970-01-01
        • 1970-01-01
        • 2011-10-22
        • 2011-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-18
        相关资源
        最近更新 更多