Как сгруппировать переключатели Windows Form?

Как я могу сгруппировать переключатели в приложении Windows Form (очень похоже на список радиообъектов ASP.NET!)?

Таким образом, я могу переключаться между каждым случаем, выбранным из вариантов.


person MW.    schedule 01.02.2010    source источник
comment
Вы можете взглянуть на Windows Forms RadioButtonList   -  person Reza Aghaei    schedule 17.08.2017
comment
См. Снимок экрана: stackoverflow.com/a/46424314/984780   -  person Luis Perez    schedule 08.05.2018


Ответы (9)


Поместите все переключатели для группы в объект-контейнер, например Panel или GroupBox. Это автоматически сгруппирует их в Windows Forms.

person Steve Danner    schedule 01.02.2010
comment
@mohammadsadeghsaati Вопрос касался RadioButton Windows Forms, он не предоставляет свойство GroupName. - person UweB; 03.06.2014
comment
@UweB Что делать, если я не могу добавить групповые поля и панели из-за какой-либо проблемы, скажем, у меня не так много места в моей форме. Потом? - person Muhammad Saqib; 03.01.2015
comment
@MuhammadSaqib это невозможно, потому что панели могут быть нулевого размера. Я имею в виду панели с невидимыми границами и без полей - это то же самое, что и простая форма. Просто используйте правую панель - TableLayoutPanel, если вы должны сгруппировать в таблице и т. Д. - person Alex Zhukovskiy; 14.01.2016

Посмотрите, как разместить свои переключатели в GroupBox .

person AJ.    schedule 01.02.2010
comment
GroupBox не имеет отношения к переключателям. Подойдет любая тара. - person usr; 06.12.2017

Вы должны поместить все переключатели группы внутри одного контейнера, такого как GroupBox или Panel.

person Nikos Steiakakis    schedule 01.02.2010
comment
Это усложняется, когда у вас есть слои вложенных панелей, например, когда вы пытаетесь сделать что-то вроде этого. Радиокнопки конфликтуют со своими родителями. - person Agi Hammerthief; 08.09.2017

Мне нравится концепция группировки 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);
        }
    }
}
person pr0gg3r    schedule 26.04.2013
comment
Это пригодилось мне в ситуации, когда мне понадобились RadioButtons в группе внутри TableLayoutPanel - спасибо! - person pelazem; 01.02.2014
comment
Я пытаюсь использовать этот класс для одной из моих собственных форм, но не могу отобразить элемент управления поверх окна группы (как если бы это заголовок окна группы). Он предназначен для использования в качестве переключателя верхнего уровня (id est, группа для этого переключателя является панелью в корне формы, а групповое поле является одноуровневым). Есть ли какой-нибудь пример кода о том, как использовать этот класс для достижения этой цели? - person Agi Hammerthief; 09.09.2017
comment
Я бы написал IEnumerable<Control> arbControls = null; вместо использования dynamic. var маскирует это еще больше, и поэтому я обычно использую в своем коде только явные типы. В остальном, очень хорошая работа, и большое спасибо за то, что поделились этим! +1 - person sɐunıɔןɐqɐp; 30.09.2019

Радиокнопка без панели

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);
}
person Suat Erenler    schedule 12.08.2014

Поместите переключатели внутри GroupBox (или другой панели)

введите описание изображения здесь

person Luis Perez    schedule 26.09.2017

GroupBox лучше. Но не только групповое поле, даже вы можете использовать Panels (System.Windows.Forms.Panel).

  • Это очень полезно при разработке диалогового окна настройки Интернет-протокола версии 4. (Проверьте его на своем компьютере (Windows), тогда вы сможете понять поведение)
person Elshan    schedule 07.03.2013

Все переключатели внутри контейнера общего доступа находятся в одной группе по умолчанию. Значит, если вы отметите один из них - остальные будут сняты. Если вы хотите создать независимые группы переключателей, вы должны разместить их в разных контейнерах, таких как Group Box, или контролировать их состояние Проверено с помощью кода позади.

person Mr.B    schedule 11.04.2018

Если вы не можете поместить их в один контейнер, вам необходимо написать код для изменения состояния checked каждого 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;
}
person fat    schedule 24.06.2016
comment
Это поставит вас в бесконечный цикл ,,, - person Michael Sandler; 03.01.2019