Wie kann ich die Optionsfelder in der Windows Form-Anwendung gruppieren (ähnlich wie die Radiobutton-Liste von ASP.NET!)?
So kann ich zwischen den aus den Optionen ausgewählten Fällen wechseln.
Wie kann ich die Optionsfelder in der Windows Form-Anwendung gruppieren (ähnlich wie die Radiobutton-Liste von ASP.NET!)?
So kann ich zwischen den aus den Optionen ausgewählten Fällen wechseln.
Antworten:
Fügen Sie alle Optionsfelder für eine Gruppe in ein Containerobjekt wie a Panel
oder a ein GroupBox
. Dadurch werden sie automatisch in Windows Forms zusammengefasst.
Sehen Sie sich an, wie Sie Ihre Optionsfelder in einer GroupBox platzieren .
Sie sollten alle Optionsfelder der Gruppe in demselben Container wie einer GroupBox oder einem Panel platzieren.
Ich mag das Konzept, RadioButtons in WPF zu gruppieren. Es gibt eine Eigenschaft GroupName
, die angibt, welche RadioButton-Steuerelemente sich gegenseitig ausschließen ( http://msdn.microsoft.com/de-de/library/system.windows.controls.radiobutton.aspx ).
Also habe ich eine abgeleitete Klasse für WinForms geschrieben, die diese Funktion unterstützt:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Windows.Forms.VisualStyles;
using System.Drawing;
using System.ComponentModel;
namespace Use.your.own
{
public class AdvancedRadioButton : CheckBox
{
public enum Level { Parent, Form };
[Category("AdvancedRadioButton"),
Description("Gets or sets the level that specifies which RadioButton controls are affected."),
DefaultValue(Level.Parent)]
public Level GroupNameLevel { get; set; }
[Category("AdvancedRadioButton"),
Description("Gets or sets the name that specifies which RadioButton controls are mutually exclusive.")]
public string GroupName { get; set; }
protected override void OnCheckedChanged(EventArgs e)
{
base.OnCheckedChanged(e);
if (Checked)
{
var arbControls = (dynamic)null;
switch (GroupNameLevel)
{
case Level.Parent:
if (this.Parent != null)
arbControls = GetAll(this.Parent, typeof(AdvancedRadioButton));
break;
case Level.Form:
Form form = this.FindForm();
if (form != null)
arbControls = GetAll(this.FindForm(), typeof(AdvancedRadioButton));
break;
}
if (arbControls != null)
foreach (Control control in arbControls)
if (control != this &&
(control as AdvancedRadioButton).GroupName == this.GroupName)
(control as AdvancedRadioButton).Checked = false;
}
}
protected override void OnClick(EventArgs e)
{
if (!Checked)
base.OnClick(e);
}
protected override void OnPaint(PaintEventArgs pevent)
{
CheckBoxRenderer.DrawParentBackground(pevent.Graphics, pevent.ClipRectangle, this);
RadioButtonState radioButtonState;
if (Checked)
{
radioButtonState = RadioButtonState.CheckedNormal;
if (Focused)
radioButtonState = RadioButtonState.CheckedHot;
if (!Enabled)
radioButtonState = RadioButtonState.CheckedDisabled;
}
else
{
radioButtonState = RadioButtonState.UncheckedNormal;
if (Focused)
radioButtonState = RadioButtonState.UncheckedHot;
if (!Enabled)
radioButtonState = RadioButtonState.UncheckedDisabled;
}
Size glyphSize = RadioButtonRenderer.GetGlyphSize(pevent.Graphics, radioButtonState);
Rectangle rect = pevent.ClipRectangle;
rect.Width -= glyphSize.Width;
rect.Location = new Point(rect.Left + glyphSize.Width, rect.Top);
RadioButtonRenderer.DrawRadioButton(pevent.Graphics, new System.Drawing.Point(0, rect.Height / 2 - glyphSize.Height / 2), rect, this.Text, this.Font, this.Focused, radioButtonState);
}
private IEnumerable<Control> GetAll(Control control, Type type)
{
var controls = control.Controls.Cast<Control>();
return controls.SelectMany(ctrl => GetAll(ctrl, type))
.Concat(controls)
.Where(c => c.GetType() == type);
}
}
}
IEnumerable<Control> arbControls = null;
anstatt dynamisch zu verwenden. Die var
Masken machen es noch mehr, und deshalb verwende ich normalerweise nur explizite Typen in meinem Code. Ansonsten sehr gute Arbeit, und vielen Dank für das Teilen! +1
Optionsfeld ohne Bedienfeld
public class RadioButton2 : RadioButton
{
public string GroupName { get; set; }
}
private void RadioButton2_Clicked(object sender, EventArgs e)
{
RadioButton2 rb = (sender as RadioButton2);
if (!rb.Checked)
{
foreach (var c in Controls)
{
if (c is RadioButton2 && (c as RadioButton2).GroupName == rb.GroupName)
{
(c as RadioButton2).Checked = false;
}
}
rb.Checked = true;
}
}
private void Form1_Load(object sender, EventArgs e)
{
//a group
RadioButton2 rb1 = new RadioButton2();
rb1.Text = "radio1";
rb1.AutoSize = true;
rb1.AutoCheck = false;
rb1.Top = 50;
rb1.Left = 50;
rb1.GroupName = "a";
rb1.Click += RadioButton2_Clicked;
Controls.Add(rb1);
RadioButton2 rb2 = new RadioButton2();
rb2.Text = "radio2";
rb2.AutoSize = true;
rb2.AutoCheck = false;
rb2.Top = 50;
rb2.Left = 100;
rb2.GroupName = "a";
rb2.Click += RadioButton2_Clicked;
Controls.Add(rb2);
//b group
RadioButton2 rb3 = new RadioButton2();
rb3.Text = "radio3";
rb3.AutoSize = true;
rb3.AutoCheck = false;
rb3.Top = 80;
rb3.Left = 50;
rb3.GroupName = "b";
rb3.Click += RadioButton2_Clicked;
Controls.Add(rb3);
RadioButton2 rb4 = new RadioButton2();
rb4.Text = "radio4";
rb4.AutoSize = true;
rb4.AutoCheck = false;
rb4.Top = 80;
rb4.Left = 100;
rb4.GroupName = "b";
rb4.Click += RadioButton2_Clicked;
Controls.Add(rb4);
}
GroupBox
ist besser. Aber nicht nur Gruppenfeld, auch Sie können Panels
( System.Windows.Forms.Panel
) verwenden.
Alle Optionsfelder in einem Freigabecontainer befinden sich standardmäßig in derselben Gruppe . Bedeutet, wenn Sie eines davon aktivieren, werden andere deaktiviert. Wenn Sie unabhängige Gruppen von Optionsfeldern erstellen möchten, müssen Sie diese in verschiedenen Containern platzieren, z. B. Group Box
oder ihren geprüften Status durch Code dahinter steuern .
Wenn Sie sie nicht in einen Container packen können, müssen Sie Code schreiben, um den überprüften Status jedes RadioButton zu ändern :
private void rbDataSourceFile_CheckedChanged(object sender, EventArgs e)
{
rbDataSourceNet.Checked = !rbDataSourceFile.Checked;
}
private void rbDataSourceNet_CheckedChanged(object sender, EventArgs e)
{
rbDataSourceFile.Checked = !rbDataSourceNet.Checked;
}