WinForms RadioButtonListは存在しませんか?
-
06-07-2019 - |
質問
WebForms
には RadioButtonList
コントロールがあることは知っていますが、 WinForms
のコントロールは見つかりません。必要なのは、一度に1つしか選択できないように、3つのRadioButtonをグループ化することです。私はコードを介してこれを行う必要があることがわかりましたが、これは苦痛です。どこかに RadioButtonList
が表示されないのですか、それとも WinForms
に実際に存在しないのですか?
解決
GroupBoxまたはパネルを使用して、3つのRadioButtonsをグループ化できます。ここでのように。
他のヒント
ラジオボタンをグループ化する場合は、コンテナに入れるだけで十分です。グループのように機能しますが、 ComboBox
や ListBox
または CheckedListBox
は機能します。 RadioButtonList
コントロールが必要です。
Windowsフォームには、組み込みの RadioButtonList
コントロールがありません。フォーム ListBox
を派生させ、所有者描画およびラジオボタン描画を自分で行うことで、独自のコントロールを作成できます。これは、 CheckedListBox
も作成される方法です。
このように、コントロールはデータバインディングをサポートし、 DataSource
、 SelectedValue
、を含む
、 ListBox
のすべての機能を利用できます。 DisplayMember ValueMember
など。たとえば、次のように単純に使用できます。
this.radioButtonList1.DataSource = peopleTable;
this.radioButtonList1.DisplayMember = "Name";
this.radioButtonList1.ValueMember= "Id";
または、たとえば enum
の場合は、次のようにします。
this.radioButtonList1.DataSource = Enum.GetValues(typeof(DayOfWeek));
下の画像では、2番目の RadioButtonList
は、 Enabled = false;
:
また、コントロールは右から左にも対応しています:
複数列もサポートしています:
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; }
}
}
複数のラジオボタンが同じコンテナ内にあるという単純な事実により、それらは相互に排他的になります。この動作を自分でコーディングする必要はありません。 Matthewの提案に従って、それらをPanelまたはGroupBoxに入れるだけです