Какая радио кнопка в группе проверена?

Использование WinForms; Есть ли лучший способ найти зарегистрированный RadioButton для группы? Мне кажется, что код ниже не нужен. Когда вы проверяете другой RadioButton, тогда он знает, какой из них следует снять, поэтому он должен знать, что проверяется. Как я могу извлечь эту информацию, не делая много операторов if (или коммутатор).

     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

Вы можете использовать LINQ:

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

Обратите внимание, что для этого требуется, чтобы все переключатели находились непосредственно в одном контейнере (например, Panel или Form) и что в контейнере есть только одна группа. Если это не так, вы можете сделать List<RadioButton> в своем конструкторе для каждой группы, а затем написать list.FirstOrDefault(r => r.Checked).

Ответ 2

Вы можете подключить 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;
    }
}

Ответ 3

Для тех, у кого нет 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;
}

Ответ 4

ОП хотела получить проверенную RadioButton BY GROUP. Хотя ответ @SLaks отличный, он не отвечает на главный вопрос ОП. Чтобы улучшить ответ @SLaks, просто сделайте LINQ еще на один шаг вперед.

Вот пример из моего собственного рабочего кода. В обычном WPF мои RadioButton содержатся в Grid (называемой "myGrid") с кучей других типов элементов управления. У меня есть две разные группы RadioButton в Grid.

Чтобы получить проверенную кнопку RadioButton из определенной группы:

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

Если в вашем коде нет возможности проверки SingleOrDefault() RadioButton, используйте SingleOrDefault() (если я не использую кнопки с тремя состояниями, я всегда устанавливаю одну кнопку "IsChecked" в качестве выбора по умолчанию.)

Ответ 5

Вы можете использовать событие CheckedChanged для всех ваших RadioButtons. Sender будут отмечены и отмечены флажки RadioButtons.

Ответ 6

Вы можете использовать метод расширения для итерации коллекции RadioButton Parent.Controls. Это позволяет вам запрашивать другие 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;

Ответ 7

В дополнение к проводке CheckedChangedEvent можно использовать свойство "Tag" элемента управления, чтобы различать переключатели... альтернативой (альтернативный вариант спагетти) было бы свойство "TabIndex", P

Ответ 8

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

Мой взлом в С# должен использовать тег для установки значения, и когда я делаю выбор из группы, я читаю значение тега выбранного радиообмена. В этом примере directionGroup - это группа, в которой у меня есть четыре пять переключателей с "None" и "NE", "SE", "NW" и "SW" в качестве тегов на других четырех радиокнопки.

Я проактивно использовал кнопку, чтобы зафиксировать значение отмеченной кнопки, потому что, поскольку назначение одного обработчика событий всем кнопкам "Событие CHeckCHanged" вызывает кнопку "КАЖДЫЙ", потому что изменение одного изменяет их все. Таким образом, значение отправителя всегда является первым 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, я тестировал и использовал это в своей работе.

Джои

Ответ 9

если вы хотите сохранить выделение в файл или любое другое и вызвать его позже, вот что я делаю

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;

Ответ 10

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

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.

Обновление: выяснилось, что моя первая попытка не сработала, если в элементе управления нет переключателя. Я добавил блок try и catch, чтобы исправить это, и теперь этот метод работает.

Ответ 11

Для этого в GroupBox есть событие Validated, если вы используете 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();
     }

Ответ 12

Для разработчиков, использующих 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