ฉันจะจัดกลุ่มปุ่มตัวเลือก Windows Form ได้อย่างไร


315

ฉันจะจัดกลุ่มปุ่มตัวเลือกในแอปพลิเคชัน Windows Form ได้อย่างไร (เช่น radiobuttonlist ของ ASP.NET!)

ดังนั้นฉันสามารถสลับระหว่างแต่ละกรณีที่เลือกจากตัวเลือก



ดูภาพหน้าจอ: stackoverflow.com/a/46424314/984780
Luis Perez

คำตอบ:


425

ใส่ปุ่มทั้งหมดสำหรับกลุ่มในคอนเทนเนอร์วัตถุเหมือนหรือPanel GroupBoxที่จะจัดกลุ่มเข้าด้วยกันโดยอัตโนมัติใน Windows Forms


13
@mohammadsadeghsaati คำถามคือเกี่ยวกับ RadioButton ฟอร์ม Windows มันไม่เปิดเผยคุณสมบัติ GroupName
UweB

2
@UWB ถ้าฉันไม่สามารถเพิ่มกล่องและพาเนลกลุ่มเนื่องจากปัญหาใด ๆ ให้บอกว่าฉันไม่มีพื้นที่ในแบบฟอร์มของฉันมาก แล้ว?
มูฮัมหมัด Saqib

2
@ MuhammadSaqib เป็นไปไม่ได้เพราะพาเนลอาจมีขนาดเป็นศูนย์ ฉันหมายถึงแผงที่มีเส้นขอบที่มองไม่เห็นและไม่มีระยะขอบเหมือนกับแบบธรรมดา เพียงใช้พาเนลที่ถูกต้อง - TableLayoutPanel ถ้าคุณควรจะจัดกลุ่มในตาราง ฯลฯ
Alex Zhukovskiy

38

มองไปที่การวางปุ่มของคุณในGroupBox


1
GroupBox ไม่เกี่ยวข้องกับปุ่มตัวเลือกทั้งหมด ภาชนะใด ๆ จะทำ
usr

30

คุณควรวางปุ่มตัวเลือกทั้งหมดของกลุ่มไว้ในที่เก็บเดียวกันเช่น GroupBox หรือแผงควบคุม


1
มันได้รับซับซ้อนเมื่อคุณได้มีชั้นของแผ่นซ้อนกันเช่นเมื่อคุณกำลังพยายามที่จะทำบางสิ่งบางอย่างที่มีลักษณะเช่นนี้ ปุ่มตัวเลือกขัดแย้งกับผู้ปกครอง
Agi Hammerthief

24

ฉันชอบแนวคิดของการจัดกลุ่ม RadioButtons ใน WPF มีคุณสมบัติGroupNameที่ระบุว่าตัวควบคุม RadioButton ใดเป็นเอกสิทธิ์เฉพาะบุคคล ( http://msdn.microsoft.com/de-de/library/system.windows.controls.radiobutton.aspx )

ดังนั้นฉันจึงเขียนคลาสที่ได้รับสำหรับ WinForms ที่รองรับคุณสมบัตินี้:

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);
        }
    }
}

3
สิ่งนี้มีประโยชน์สำหรับฉันในสถานการณ์ที่ฉันต้องการ RadioButtons ในกลุ่มภายใน TableLayoutPanel - ขอบคุณ!
pelazem

ฉันพยายามที่จะใช้คลาสนี้สำหรับหนึ่งในรูปแบบของฉันเอง แต่มีปัญหาในการควบคุมเพื่อแสดงที่ด้านบนของกล่องกลุ่ม (ราวกับว่ามันเป็นชื่อของกล่องกลุ่ม) มันมีไว้เพื่อทำหน้าที่เป็นปุ่มตัวเลือกระดับบนสุด ( id est , กลุ่มสำหรับปุ่มตัวเลือกนี้จะเป็นพาเนลที่รูทของฟอร์มและกล่องกลุ่มเป็นพี่น้อง) มีรหัสตัวอย่างในการใช้คลาสนี้เพื่อให้บรรลุหรือไม่
Agi Hammerthief

ฉันจะเขียนIEnumerable<Control> arbControls = null;แทนการใช้ไดนามิก มาสvarก์มันมากขึ้นและนั่นเป็นสาเหตุที่ฉันมักจะใช้เฉพาะประเภทที่ชัดเจนในรหัสของฉัน มิฉะนั้นเป็นงานที่ดีมากและขอบคุณมากสำหรับการแบ่งปันนี้! +1
sɔunıɔןɐqɐp

11

ปุ่มตัวเลือกที่ไม่มีแผง

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);
}


5

GroupBoxจะดีกว่า แต่ไม่เพียง แต่กล่องกลุ่มแม้คุณสามารถใช้Panels( System.Windows.Forms.Panel)

  • มีประโยชน์มากเมื่อคุณกำลังออกแบบกล่องโต้ตอบการตั้งค่า Internet Protocol รุ่น 4 (ตรวจสอบกับพีซีของคุณ (windows) จากนั้นคุณสามารถเข้าใจพฤติกรรม)

5

ทุกปุ่มด้านในของภาชนะที่ใช้ร่วมกันอยู่ในกลุ่มเดียวกันโดยค่าเริ่มต้น หมายความว่าถ้าคุณเลือกหนึ่งในนั้น - อื่น ๆ จะไม่ถูกตรวจสอบ หากคุณต้องการสร้างกลุ่มอิสระจากปุ่มคุณจะต้องตั้งอยู่พวกเขาเข้าไปในภาชนะบรรจุที่แตกต่างกันเช่นGroup Box, หรือการควบคุมของพวกเขายืมของรัฐผ่านรหัสหลัง


4

หากคุณไม่สามารถใส่ไว้ในที่เก็บเดียวคุณต้องเขียนโค้ดเพื่อเปลี่ยนสถานะที่เลือกของRadioButtonแต่ละตัว:

private void rbDataSourceFile_CheckedChanged(object sender, EventArgs e)
{
    rbDataSourceNet.Checked = !rbDataSourceFile.Checked;
}

private void rbDataSourceNet_CheckedChanged(object sender, EventArgs e)
{
  rbDataSourceFile.Checked = !rbDataSourceNet.Checked;
}

สิ่งนี้จะนำคุณเข้าสู่วงวนไม่สิ้นสุด ,,,
Michael Sandler
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.