Tombol Radio mana dalam grup yang dicentang?

118

Menggunakan WinForms; Apakah ada cara yang lebih baik untuk menemukan RadioButton yang dicentang untuk grup? Menurut saya, kode di bawah ini seharusnya tidak diperlukan. Ketika Anda mencentang RadioButton yang berbeda, maka RadioButton akan tahu mana yang harus dihapus centangnya… sehingga harus tahu mana yang dicentang. Bagaimana cara menarik informasi itu tanpa melakukan banyak pernyataan if (atau sakelar).

     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;
     }
Billy
sumber
1
Kode yang mendasarinya tidak tahu mana yang harus dihapus centangnya, itu hanya mengulang semua kontrol RadioButton di bawah induk yang sama dari kontrol yang diubah dan menghapus centang yang sebelumnya diperiksa.
João Angelo
1
Apakah Anda menggunakan WinForms atau ASP.Net?
SLaks

Jawaban:

219

Anda bisa menggunakan LINQ:

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

Perhatikan bahwa ini mengharuskan semua tombol radio berada langsung di wadah yang sama (misalnya, Panel atau Formulir), dan hanya ada satu grup di wadah. Jika bukan itu masalahnya, Anda dapat membuat List<RadioButton>s di konstruktor Anda untuk setiap grup, lalu tulis list.FirstOrDefault(r => r.Checked).

SLaks
sumber
Haruskah itu s.FirstOrDefaultbukan list.FirstOrDefaultdi paragraf kedua dari jawaban Anda?
@Phoenix: sadalah bentuk jamak, bukan nama variabel.
SLaks
Jawaban yang sangat baik, tetapi tidak benar-benar menjawab pertanyaan utama OP. Lihat jawaban saya.
D'Hag
Untuk Anda vb.net teman-teman, saya akan menghemat perjalanan ke konverter Telerik: Dim checkButton = radConnections.Controls.OfType (Of RadioButton) (). FirstOrDefault (Fungsi (r) r.Checked)
JoshYates1980
36

Anda dapat menyambungkan CheckedEvents dari semua tombol ke satu penangan. Di sana Anda dapat dengan mudah mendapatkan Kotak Centang yang benar.

// 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;
    }
}
Polisi
sumber
Seharusnya ini sebagai gantinya - if (((RadioButton) sender]. Diperiksa)
Frank Tzanabetis
1
Tidak ada CheckedChanged di WPF RadioButton dari mana Anda mendapatkannya?
Murhaf Sousli
26

Bagi mereka yang tidak memiliki 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;
}
João Angelo
sumber
12

OP ingin mencentang RadioButton OLEH GROUP. Meskipun jawaban @SLaks sangat bagus, itu tidak benar-benar menjawab pertanyaan utama OP. Untuk meningkatkan jawaban @SLaks, cukup gunakan LINQ selangkah lebih maju.

Inilah contoh dari kode kerja saya sendiri. Sesuai WPF normal, RadioButtons saya terkandung dalam fileGrid (bernama "myGrid") dengan sekelompok jenis kontrol lainnya. Saya memiliki dua grup RadioButton berbeda di Grid.

Untuk mendapatkan RadioButton yang dicentang dari grup tertentu:

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

Jika kode Anda memiliki kemungkinan tidak ada RadioButtons yang diperiksa, maka gunakan SingleOrDefault()(Jika saya tidak menggunakan tombol tri-state, maka saya selalu menetapkan satu tombol "IsChecked" sebagai pilihan default.)

D'Hag
sumber
1
r.GroupName == "GroupName" dan r.IsChecked adalah tipe yang berbeda (bool dan bool?), Anda harus menggunakan r.IsChecked.Value, yang berjenis bool.
Mike
1
coba .Where(r => r.GroupName == "GroupName" && r.IsChecked == true)karena r.IsCheckedadalah properti bool nullable.
Firnas
apa yang dirujuk myGrid di sini.
Unnikrishnan
@ Mike Bisakah Anda tahu apa itu "radioButtons" di sini?
Bella Swan
1
@BellaSwan - lihat kode - Anda membuat daftar semua tombol radio dan menetapkannya ke variabel. Dan kemudian, pada variabel yang sama Anda perlu menjalankan pilihan Where dan menetapkannya ke rbTarget.
Mike
5

Anda dapat menggunakan acara CheckedChanged untuk semua RadioButtons Anda. Senderakan menjadi RadioButtons yang tidak dicentang dan dicentang.

tanascius.dll
sumber
1

Anda dapat menggunakan metode Ekstensi untuk mengulang koleksi Parent.Controls RadioButton. Ini memungkinkan Anda untuk menanyakan RadioButtons lain dalam lingkup yang sama. Dengan menggunakan dua metode ekstensi, Anda dapat menggunakan yang pertama untuk menentukan apakah ada RadioButtons dalam grup yang dipilih, kemudian menggunakan yang kedua untuk mendapatkan pemilihan. Bidang RadioButton Tag dapat digunakan untuk menahan Enum untuk mengidentifikasi setiap RadioButton dalam grup:

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

Berikut pola penggunaan yang khas:

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

Selain kabel CheckedChangedEvent, seseorang dapat menggunakan properti Controls "Tag" untuk membedakan antara tombol radio ... alternatif (kode spaghetti) adalah properti "TabIndex"; P

Binkan Gaji
sumber
itu berarti Anda dapat menggunakan dengan cepat switch-case pada id radiobutton yang dipilih (menggunakan properti System.Windows.Forms.Control.Tag) tolong jangan menilai jika Anda tidak mengerti penambahan saya pada pertanyaan tersebut.
Binkan Gaji
1

Kadang-kadang dalam situasi seperti ini saya merindukan masa muda saya, ketika Access adalah racun pilihan saya, dan saya dapat memberikan nilai tersendiri pada setiap tombol radio dalam grup.

Retasan saya di C # adalah menggunakan tag untuk mengatur nilainya, dan ketika saya membuat pilihan dari grup, saya membaca nilai tag dari radiobutton yang dipilih. Dalam contoh ini, directionGroup adalah grup di mana saya memiliki empat lima tombol radio dengan "None" dan "NE", "SE", "NW" dan "SW" sebagai tag pada empat radiobuttons lainnya.

Saya secara proaktif menggunakan tombol untuk menangkap nilai dari tombol yang dicentang, karena menugaskan satu event handler ke semua event tombol 'CHeckCHanged' menyebabkan tombol SETIAP menyala, karena mengubah satu mengubah semuanya. Jadi nilai pengirim selalu menjadi RadioButton pertama di grup. Sebagai gantinya, saya menggunakan metode ini ketika saya perlu mencari tahu mana yang dipilih, dengan nilai yang ingin saya ambil di properti Tag dari setiap 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, saya telah menguji dan menggunakan ini dalam pekerjaan saya.

Joey

Joseph Morgan
sumber
Hanya memodifikasi hasil 'FormatableString', saya dapat menggunakan kode dalam program saya. Saya juga tidak mengetahui Tag radioButton. Beginilah seharusnya jawabannya. Tuan yang hebat.
Unnikrishnan
0

jika Anda ingin menyimpan pilihan ke file atau lainnya dan memanggilnya nanti, inilah yang saya lakukan

string[] lines = new string[1];

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

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

kemudian sebut dengan

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

Jika Anda ingin mendapatkan indeks tombol radio yang dipilih di dalam kontrol, Anda dapat menggunakan metode ini:

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

Contoh penggunaan:

int index = getCheckedRadioButton(panel1);

Kode tersebut tidak diuji dengan baik, tetapi tampaknya urutan indeks adalah dari kiri ke kanan dan dari atas ke bawah, seperti saat membaca teks. Jika tidak ada tombol radio yang ditemukan, metode akan mengembalikan -1.

Pembaruan: Ternyata upaya pertama saya tidak berhasil jika tidak ada tombol radio di dalam kontrol. Saya menambahkan blok coba dan tangkap untuk memperbaikinya, dan metode ini sekarang tampaknya berfungsi.

matsolof.dll
sumber
0

GroupBox memiliki acara yang divalidasi untuk tujuan ini, jika Anda menggunakan 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();
     }
Bede Amarasekara
sumber
0

Untuk pengembang yang menggunakan 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

sumber