เลือกปุ่มตัวเลือกใดในกลุ่มนี้


118

ใช้ 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
รหัสพื้นฐานไม่ทราบว่าจะยกเลิกการเลือกตัวใดเพียงแค่ย้ำการควบคุม RadioButton ทั้งหมดที่อยู่ด้านล่างพาเรนต์เดียวกันของการควบคุมที่เปลี่ยนไปและยกเลิกการเลือกตัวควบคุมที่ตรวจสอบไว้ก่อนหน้านี้
João Angelo

1
คุณใช้ WinForms หรือ ASP.Net หรือไม่?
SLaks

คำตอบ:


219

คุณสามารถใช้ LINQ:

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

โปรดทราบว่าสิ่งนี้ต้องการให้ปุ่มตัวเลือกทั้งหมดอยู่ในคอนเทนเนอร์เดียวกันโดยตรง (เช่นแผงควบคุมหรือฟอร์ม) และมีเพียงกลุ่มเดียวในคอนเทนเนอร์ หากที่ไม่กรณีที่คุณสามารถทำในคอนสตรัคของคุณสำหรับแต่ละกลุ่มเขียนแล้วList<RadioButton>list.FirstOrDefault(r => r.Checked)


ที่ควรจะเป็นs.FirstOrDefaultแทนlist.FirstOrDefaultในวรรคสองของคำตอบของคุณหรือไม่

@Phoenix: sเป็นพหูพจน์ไม่ใช่ชื่อตัวแปร
SLaks

คำตอบที่ดีเยี่ยม แต่ไม่ได้ตอบคำถามหลักของ OP ดูคำตอบของฉัน
D'Hag

สำหรับพวกคุณ vb.net ฉันจะช่วยให้คุณเดินทางไปยังตัวแปลง Telerik: Dim checkedButton = radConnections.Controls.OfType (Of RadioButton) () FirstOrDefault (Function (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) ผู้ส่ง) ตรวจสอบ)
Frank Tzanabetis

1
ไม่มี CheckedChanged ใน RadioButton ของ WPF คุณเอามาจากไหน
Murhaf Sousli

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

OP ต้องการรับ RadioButton BY GROUP ที่ตรวจสอบแล้ว ในขณะที่คำตอบของ @SLaks นั้นยอดเยี่ยม แต่ก็ไม่ได้ตอบคำถามหลักของ OP ในการปรับปรุงคำตอบของ @SLaks ให้ใช้ LINQ ไปอีกขั้น

นี่คือตัวอย่างจากรหัสการทำงานของฉันเอง ตาม WPF ปกติ RadioButtons ของฉันจะอยู่ในGrid(ชื่อ "myGrid") พร้อมกับตัวควบคุมประเภทอื่น ๆ อีกมากมาย ฉันมีกลุ่ม RadioButton สองกลุ่มที่แตกต่างกันใน Grid

ในการรับ 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 เป็นประเภทที่แตกต่างกัน (บูลและบูล?) คุณควรใช้ r.IsChecked.Value ซึ่งเป็นประเภทบูล
Mike

1
ลอง.Where(r => r.GroupName == "GroupName" && r.IsChecked == true)เพราะr.IsCheckedคุณสมบัติบูลเป็นโมฆะ
Firnas

myGrid อ้างถึงอะไรที่นี่
Unnikrishnan

@ ไมค์บอกได้ไหมว่า "radioButtons" ที่นี่คืออะไร?
Bella Swan

1
@BellaSwan - ดูรหัส - คุณสร้างรายการปุ่มตัวเลือกทั้งหมดและกำหนดให้กับตัวแปร จากนั้นบนตัวแปรเดียวกันคุณต้องรันการเลือก Where และกำหนดให้กับ rbTarget
Mike

5

คุณสามารถใช้เหตุการณ์CheckedChangedสำหรับ RadioButtons ทั้งหมดของคุณ Senderจะเป็น RadioButtons ที่ไม่ถูกตรวจสอบและถูกตรวจสอบ


1

คุณสามารถใช้วิธีการขยายเพื่อวนซ้ำคอลเลกชัน Parent.Controls ของ RadioButton สิ่งนี้ช่วยให้คุณสามารถค้นหา RadioButtons อื่น ๆ ในขอบเขตเดียวกันได้ ใช้วิธีการขยายสองวิธีคุณสามารถใช้วิธีแรกกำหนดว่าจะเลือกปุ่ม 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) โปรดอย่าให้คะแนนลงหากคุณไม่เข้าใจการเพิ่มเติมของฉันในคำถาม
Binkan Salaryman

1

บางครั้งในสถานการณ์เช่นนี้ฉันคิดถึงวัยเยาว์เมื่อ Access เป็นพิษที่ฉันเลือกและฉันสามารถให้ปุ่มตัวเลือกแต่ละปุ่มในกลุ่มมีคุณค่าในตัวเอง

การแฮ็กของฉันใน C # คือการใช้แท็กเพื่อตั้งค่าและเมื่อฉันทำการเลือกจากกลุ่มฉันอ่านค่าของแท็กของปุ่มเรดิโอที่เลือก ในตัวอย่างนี้directionGroupคือกลุ่มที่ฉันมีปุ่มตัวเลือกสี่ห้าปุ่มที่มี "None" และ "NE", "SE", "NW" และ "SW" เป็นแท็กบนวิทยุอีกสี่ปุ่ม

ฉันใช้ปุ่มเพื่อจับค่าของปุ่มที่เลือกในเชิงรุกเนื่องจากการกำหนดตัวจัดการเหตุการณ์หนึ่งตัวให้กับเหตุการณ์ CHeckCHanged ของปุ่มทั้งหมดทำให้ปุ่มแต่ละปุ่มเริ่มทำงานเนื่องจากการเปลี่ยนหนึ่งปุ่มจะเปลี่ยนทั้งหมด ดังนั้นค่าของผู้ส่งจึงเป็น RadioButton ตัวแรกในกลุ่มเสมอ แต่ฉันใช้วิธีนี้เมื่อฉันต้องการค้นหาว่าตัวเลือกใดถูกเลือกพร้อมกับค่าที่ฉันต้องการดึงในคุณสมบัติแท็กของ 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' ฉันสามารถใช้รหัสในโปรแกรมของฉันได้ ฉันยังไม่ทราบถึง radioButton Tag นี่คือคำตอบที่ควรจะเป็น ท่านผู้ยิ่งใหญ่.
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

อัปเดต: ปรากฎว่าความพยายามครั้งแรกของฉันไม่ได้ผลหากไม่มีปุ่มตัวเลือกในการควบคุม ฉันได้เพิ่มบล็อก try and catch เพื่อแก้ไขและตอนนี้วิธีนี้ดูเหมือนจะใช้งานได้


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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.