Wie gruppiere ich Windows Form-Optionsfelder?

Antworten:

425

Fügen Sie alle Optionsfelder für eine Gruppe in ein Containerobjekt wie a Paneloder a ein GroupBox. Dadurch werden sie automatisch in Windows Forms zusammengefasst.

Steve Danner
quelle
13
@mohammadsadeghsaati Die Frage betraf den Windows Forms RadioButton. Es wird keine GroupName-Eigenschaft verfügbar gemacht.
UweB
2
@UweB Was ist, wenn ich aufgrund eines Problems keine Gruppenfelder und Bedienfelder hinzufügen kann? Nehmen wir an, ich habe nicht viel Platz in meinem Formular. Dann?
Muhammad Saqib
2
@ MuhammadSaqib ist es unmöglich, weil Panels die Größe Null haben können. Ich meine, Tafeln mit unsichtbaren Rändern und ohne Ränder sind die gleichen wie einfache Formen. Verwenden Sie einfach das rechte Feld - TableLayoutPanel, wenn Sie in Tabelle usw. gruppieren sollten
Alex Zhukovskiy
38

Sehen Sie sich an, wie Sie Ihre Optionsfelder in einer GroupBox platzieren .

AJ.
quelle
1
GroupBox hat nichts mit Optionsfeldern zu tun. Jeder Container reicht aus.
usr
30

Sie sollten alle Optionsfelder der Gruppe in demselben Container wie einer GroupBox oder einem Panel platzieren.

Nikos Steiakakis
quelle
1
Es wird kompliziert, wenn Sie Schichten verschachtelter Bedienfelder haben, z. B. wenn Sie versuchen, etwas zu tun , das so aussieht . Die Optionsfelder stehen in Konflikt mit ihren Eltern.
Agi Hammerthief
24

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);
        }
    }
}
pr0gg3r
quelle
3
Dies war praktisch für mich in einer Situation, in der ich RadioButtons in einer Gruppe in einem TableLayoutPanel benötigte - danke!
Pelazem
Ich versuche, diese Klasse für eines meiner eigenen Formulare zu verwenden, habe jedoch Probleme, das Steuerelement über einem Gruppenfeld anzuzeigen (als wäre es der Titel des Gruppenfelds). Es soll als Optionsfeld der obersten Ebene dienen ( id est , die Gruppe für dieses Optionsfeld ist ein Feld im Stammverzeichnis des Formulars und das Gruppenfeld ist ein Geschwister). Gibt es einen Beispielcode, wie diese Klasse verwendet werden kann, um dies zu erreichen?
Agi Hammerthief
Ich würde schreiben IEnumerable<Control> arbControls = null;anstatt dynamisch zu verwenden. Die varMasken 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
sɐunıɔ ןɐ qɐp
11

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);
}
Suat Erenler
quelle
7

Fügen Sie Optionsfelder in die GroupBox (oder ein anderes Bedienfeld) ein.

Geben Sie hier die Bildbeschreibung ein

Luis Perez
quelle
5

GroupBoxist besser. Aber nicht nur Gruppenfeld, auch Sie können Panels( System.Windows.Forms.Panel) verwenden.

  • Dies ist sehr nützlich, wenn Sie den Einstellungsdialog für Internet Protocol Version 4 entwerfen. (Überprüfen Sie dies mit Ihrem PC (Windows), dann können Sie das Verhalten verstehen.)
Elshan
quelle
5

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 Boxoder ihren geprüften Status durch Code dahinter steuern .

Mr.B.
quelle
4

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;
}
Fett
quelle
Dies wird Sie in eine Endlosschleife bringen ,,,
Michael Sandler