WinForms RadioButtonList не существует? - PullRequest
7 голосов
/ 19 июня 2009

Я знаю, что WebForms имеет RadioButtonList элемент управления, но я не могу найти его для WinForms. Мне нужно сгруппировать 3 кнопки RadioButton, чтобы одновременно можно было выбрать только 1. Я обнаружил, что я должен сделать это с помощью кода, что является болью. Я просто где-то не вижу RadioButtonList, или его действительно нет в WinForms?

Ответы [ 3 ]

10 голосов
/ 28 декабря 2016

Если вы просто хотите сгруппировать переключатели, достаточно поместить их в контейнер, тогда они будут действовать как группа, но если вам нужно связать данные, например, как ComboBox или ListBox или CheckedListBoxработает, вам нужен RadioButtonList элемент управления.

Windows формы не имеют встроенного RadioButtonList элемента управления.Вы можете создать свой собственный элемент управления, извлекая форму ListBox и заставляя ее рисовать владельца и рисовать переключатели самостоятельно.Это способ, которым создается CheckedListBox.

Таким образом, элемент управления поддерживает привязку данных и будет использовать все функции ListBox, включая DataSource, SelectedValue, DisplayMember, ValueMember и т. Д.Например, вы можете просто использовать его следующим образом:

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

Или, например, для enum, просто так:

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

На изображении ниже второе RadioButtonListотключается настройкой Enabled = false;:

enter image description here enter image description here

Также управление поддерживает также справа налево:

enter image description here

Он также поддерживает несколько столбцов:

enter image description here

RadioButtonList

Вот исходный код для управления.Вы можете использовать его как обычный 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; }
    }
}
7 голосов
/ 19 июня 2009

Очевидно, нет .

Вы можете сгруппировать три RadioButton вместе, используя GroupBox или Panel , как здесь .

4 голосов
/ 19 июня 2009

Простой факт, что несколько переключателей находятся в одном контейнере, делает их взаимоисключающими, вам не нужно кодировать это поведение самостоятельно. Просто поместите их в Panel или GroupBox в соответствии с предложением Мэтью

...