Який перемикач у групі перевіряється?


118

Використання WinForms; Чи є кращий спосіб знайти перевірений RadioButton для групи? Мені здається, що код нижче не повинен бути необхідним. Якщо ви перевіряєте іншу RadioButton, то вона знає, яку зніміть… та знає, що перевірено. Як я витягую цю інформацію, не роблячи багато, якщо заяви (або перемикач).

     RadioButton rb = null;

     if (m_RadioButton1.Checked == true)
     {
        rb = m_RadioButton1;
     }
     else if (m_RadioButton2.Checked == true)
     {
        rb = m_RadioButton2;
     }
     else if (m_RadioButton3.Checked == true)
     {
        rb = m_RadioButton3;
     }

1
Код, що лежить в основі, не знає, який з них знімати, він просто ітератує всі елементи керування RadioButton під тим самим батьківським зміненим елементом керування та знімає прапорець, перевірений раніше.
Жоао Анжело,

1
Ви використовуєте WinForms або ASP.Net?
СЛАкс

Відповіді:


219

Ви можете використовувати LINQ:

var checkedButton = container.Controls.OfType<RadioButton>()
                                      .FirstOrDefault(r => r.Checked);

Зауважте, що для цього потрібно, щоб усі перемикачі були безпосередньо в одному контейнері (наприклад, панель або форма), і щоб у контейнері була лише одна група. Якщо це не так, ви можете зробити List<RadioButton>s у своєму конструкторі для кожної групи, тоді напишіть list.FirstOrDefault(r => r.Checked).


Це має бути s.FirstOrDefaultзамість list.FirstOrDefaultдругого абзацу вашої відповіді?

@Phoenix: sце плюралізація, а не ім'я змінної.
СЛАкс

Відмінна відповідь, але насправді не відповів на головне питання ОП. Дивіться мою відповідь.
D'Hag

для вас, хлопці vb.net, я врятую вам поїздку на конвертер Telerik: Dim verifiedButton = radConnections.Controls.OfType (RadioButton) (). FirstOrDefault (Функція (r) r.Checked)
JoshYates1980

36

Ви можете з'єднати CheckedEvents всіх кнопок проти одного обробника. Там ви можете легко отримати правильний прапорець.

// Wire all events into this.
private void AllCheckBoxes_CheckedChanged(Object sender, EventArgs e) {
    // Check of the raiser of the event is a checked Checkbox.
    // Of course we also need to to cast it first.
    if (((RadioButton)sender).Checked) {
        // This is the correct control.
        RadioButton rb = (RadioButton)sender;
    }
}

Має бути це замість цього - якщо (((RadioButton) відправник). Перевірено)
Френк Tzanabetis

1
У RadioButton WPF немає перевірених змін, звідки ви це взяли?
Мурхаф Суслі

26

Для тих, хто не має LINQ:

RadioButton GetCheckedRadio(Control container)
{
    foreach (var control in container.Controls)
    {
        RadioButton radio = control as RadioButton;

        if (radio != null && radio.Checked)
        {
            return radio;
        }
    }

    return null;
}

12

ОП хотіла отримати перевірену RadioButton BY GROUP. Хоча відповідь @SLaks відмінна, вона насправді не відповідає головному питанню ОП. Щоб покращити відповідь на @SLaks, просто зробіть LINQ ще на крок.

Ось приклад з мого власного робочого коду. У нормальному WPF мої RadioButtons містяться у Grid(з назвою "myGrid") з купою інших типів елементів керування. У мене в мережі є дві різні групи RadioButton.

Щоб отримати перевірену RadioButton від певної групи:

List<RadioButton> radioButtons = myGrid.Children.OfType<RadioButton>().ToList();
RadioButton rbTarget = radioButtons
      .Where(r => r.GroupName == "GroupName" && r.IsChecked)
      .Single();

Якщо ваш код не має можливості перевіряти RadioButtons, тоді використовуйте SingleOrDefault()(Якщо я не використовую трикрильні кнопки, то я завжди встановлюю одну кнопку "IsChecked" як вибір за замовчуванням.)


1
r.GroupName == "GroupName" та r.IsChecked мають різні типи (bool і bool?), ви повинні використати r.IsChecked.Value, що має тип bool.
Майк

1
спробуйте, .Where(r => r.GroupName == "GroupName" && r.IsChecked == true)тому що r.IsCheckedце незмінна властивість bool.
Фірнас

на що тут посилається myGrid.
Unnikrishnan

@Mike Не могли б ви сказати, що тут "радіо-кнопки"?
Белла Лебедь

1
@BellaSwan - подивіться на код - ви створюєте список всіх перемикачів і призначаєте його змінній. А потім на тій самій змінній потрібно запустити вибір Where і призначити її rbTarget.
Майк

5

Ви можете використовувати подію CheckedChanged для всіх ваших RadioButtons. Senderбудуть неперевіреними та перевіреними RadioButtons.


1

Для ітерації колекції Parent.Controls RadioButton можна використовувати метод розширення. Це дозволяє запитувати інші RadioButtons в тому ж обсязі. Використовуючи два способи розширення, ви можете за допомогою першого визначити, чи вибрані будь-які радіо кнопки в групі, а потім використовувати другий, щоб отримати вибір. Поле RadioButton Tag можна використовувати для утримання Enum для ідентифікації кожного RadioButton у групі:

    public static int GetRadioSelection(this RadioButton rb, int Default = -1) {
        foreach(Control c in  rb.Parent.Controls) {
            RadioButton r = c as RadioButton;
            if(r != null && r.Checked) return Int32.Parse((string)r.Tag);
        }
        return Default;
    }

    public static bool IsRadioSelected(this RadioButton rb) {
        foreach(Control c in  rb.Parent.Controls) {
            RadioButton r = c as RadioButton;
            if(r != null && r.Checked) return true;
        }
        return false;
    }

Ось типова схема використання:

if(!MyRadioButton.IsRadioSelected()) {
   MessageBox.Show("No radio selected.");
   return;
}
int selection = MyRadioButton.GetRadioSelection;

1

На додаток до проводки CheckedChangedEvent можна було б використовувати властивість Controls "Tag" для розмежування радіо кнопок ... альтернативою (код спагетті) була б властивість "TabIndex"; P


це означає, що ви можете швидко скористатися випадками переключення на вибраний ідентифікатор радіо кнопки (використовуючи властивість System.Windows.Forms.Control.Tag), будь ласка, не знижуйте, якщо ви просто не розумієте моє доповнення до питання.
Заробітна плата Бінкана

1

Іноді в таких ситуаціях я сумую за молоддю, коли Access був моєю отрутою за вибором, і я міг дати кожному перемикача в групі свою цінність.

Мій хак в C # полягає в тому, щоб використовувати тег для встановлення значення, і коли я роблю виділення з групи, я читаю значення тегу вибраної радіо кнопки. У цьому прикладі у напрямкуGroup - це група, в якій у мене є чотири п'ять радіо кнопок з "None" та "NE", "SE", "NW" та "SW" як теги на інших чотирьох радіо кнопок.

Я активно використовував кнопку, щоб захопити значення перевіреної кнопки, оскільки, якщо присвоєння одного обробника подій всім кнопок "Подія CHeckCHanged" спричиняє запуск кнопки EACH, оскільки зміна однієї змінює їх усі. Тож значення відправника завжди є першим RadioButton у групі. Натомість я використовую цей метод, коли мені потрібно з’ясувати, який із них вибрано, зі значеннями, які я хочу отримати у властивості Tag кожного RadioButton.

  private void ShowSelectedRadioButton()
    {
        List<RadioButton> buttons = new List<RadioButton>();
        string selectedTag = "No selection";
        foreach (Control c in directionGroup.Controls)
        {
            if (c.GetType() == typeof(RadioButton))
            {
                buttons.Add((RadioButton)c);
            }
        }
        var selectedRb = (from rb in buttons where rb.Checked == true select rb).FirstOrDefault();
        if (selectedRb!=null)
        {
             selectedTag = selectedRb.Tag.ToString();
        }

        FormattableString result = $"Selected Radio button tag ={selectedTag}";
        MessageBox.Show(result.ToString());
    }

FYI, я тестував і використовував це у своїй роботі.

Джої


Змінивши лише результат 'FormatableString', я зміг використати код у своїй програмі. Мені також не було відомо про тег радіозв'язку. Ось так повинні бути відповіді. Великий сер.
Unnikrishnan

0

якщо ви хочете зберегти вибір у файлі чи будь-якому іншому та зателефонувати пізніше, ось що я роблю

string[] lines = new string[1];

lines[0]  = groupBoxTes.Controls.OfType<RadioButton>()
            .FirstOrDefault(r => r.Checked).Text;

File.WriteAllLines("Config.ini", lines);

потім зателефонуйте за допомогою

string[] ini = File.ReadAllLines("Config.ini");
groupBoxTes.Controls.OfType<RadioButton>()
.FirstOrDefault(r => (r.Text == ini[0])).Checked = true;

0

Якщо ви хочете отримати індекс вибраної радіо кнопки всередині елемента керування, ви можете скористатися цим методом:

public static int getCheckedRadioButton(Control c)
{
    int i;
    try
    {
        Control.ControlCollection cc = c.Controls;
        for (i = 0; i < cc.Count; i++)
        {
            RadioButton rb = cc[i] as RadioButton;
            if (rb.Checked)
            {
                return i;
            }
        }
    }
    catch
    {
        i = -1;
    }
    return i;
}

Приклад використання:

int index = getCheckedRadioButton(panel1);

Код не так добре перевірений, але здається, що порядок індексу - зліва направо і зверху вниз, як при читанні тексту. Якщо перемикач не знайдено, метод повертає -1.

Оновлення: виявилося, що моя перша спроба не спрацювала, якщо всередині елемента управління немає кнопки. Я додав блок спробу і лову, щоб виправити це, і метод, здається, працює.


0

Для цього GroupBox має перевірену подію, якщо ви використовуєте WinForms.

private void grpBox_Validated(object sender, EventArgs e)
    {
        GroupBox g = sender as GroupBox;
        var a = from RadioButton r in g.Controls
                 where r.Checked == true select r.Name;
        strChecked = a.First();
     }

0

Для розробників, що використовують VB.NET


Private Function GetCheckedRadio(container) As RadioButton
    For Each control In container.Children
        Dim radio As RadioButton = TryCast(control, RadioButton)

        If radio IsNot Nothing AndAlso radio.IsChecked Then
            Return radio
        End If
    Next

    Return Nothing
End Function
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.