Como agrupo os botões de opção do Windows Form?

Respostas:

425

Coloque todos os botões de opção de um grupo em um objeto contêiner como a Panelou a GroupBox. Isso os agrupará automaticamente no Windows Forms.

Steve Danner
fonte
13
@mohammadsadeghsaati A pergunta era sobre o Windows Forms RadioButton, mas não expõe uma propriedade GroupName.
UweB
2
@ UweB, e se eu não puder adicionar caixas e painéis de grupo devido a algum problema, digamos que não tenho muito espaço no meu formulário. Então?
Muhammad Saqib
2
@MuhammadSaqib é impossível porque os painéis podem ter tamanho zero. Quero dizer painéis com bordas invisíveis e sem margens são os mesmos da forma simples. Basta usar painel direito - TableLayoutPanel se deve agrupar na tabela etc
Alex Zhukovskiy
38

Veja como colocar seus botões de opção em um GroupBox .

AJ.
fonte
1
O GroupBox não tem nenhuma relação com os botões de opção. Qualquer contêiner serve.
usr
30

Você deve colocar todos os botões de opção do grupo dentro do mesmo contêiner, como um GroupBox ou Panel.

Nikos Steiakakis
fonte
1
Fica complicado quando você tem camadas de painéis aninhados, como quando você está tentando fazer algo parecido com isso . Os botões de opção entram em conflito com os pais.
Agi Hammerthief
24

Eu gosto do conceito de agrupar RadioButtons no WPF. Há uma propriedade GroupNameque especifica quais controles RadioButton são mutuamente exclusivos ( http://msdn.microsoft.com/de-de/library/system.windows.controls.radiobutton.aspx ).

Então, eu escrevi uma classe derivada para o WinForms que suporta esse recurso:

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
fonte
3
Isso foi útil para mim em uma situação em que eu precisava dos RadioButtons em um grupo dentro de um TableLayoutPanel - obrigado!
precisa saber é
Estou tentando usar essa classe para um dos meus próprios formulários, mas estou tendo problemas para exibir o controle em cima de uma caixa de grupo (como se fosse o título da caixa de grupo). Destina-se a servir como o botão de opção de nível superior ( id est , o grupo para este botão de opção é um painel na raiz da forma e da caixa de grupo é um irmão). Existe algum código de exemplo sobre como usar essa classe para conseguir isso?
Agi Hammerthief
Eu escreveria em IEnumerable<Control> arbControls = null;vez de usar dinâmico. O varmascara ainda mais, e é por isso que normalmente uso apenas tipos explícitos no meu código. Caso contrário, muito bom trabalho, e muito obrigado por compartilhar isso! +1
quinta-feira 29/09/19
11

Botão de opção sem painel

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
fonte
7

Coloque botões de opção dentro do GroupBox (ou outro painel)

insira a descrição da imagem aqui

Luis Perez
fonte
5

GroupBoxé melhor.Mas não apenas a caixa de grupo, você pode usar Panels( System.Windows.Forms.Panel).

  • Isso é muito útil quando você cria a caixa de diálogo de configuração do Protocolo da Internet versão 4. (Verifique com o seu PC (Windows), para entender o comportamento)
Elshan
fonte
5

Todos os botões de opção dentro de um contêiner de compartilhamento estão no mesmo grupo por padrão . Significa, se você marcar uma delas - outras serão desmarcadas. Se você deseja criar grupos independentes de botões de opção, deve situá-los em contêineres diferentes, como Group Box, ou controlar seu estado Verificado através do código por trás .

Mr.B
fonte
4

Se você não pode colocá-los em um contêiner, precisará escrever um código para alterar o estado verificado de cada 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;
}
gordura
fonte
Isto irá colocá-lo em um loop infinito ,,,
Michael Sandler