Nút Radio nào trong nhóm được chọn?


118

Sử dụng WinForms; Có cách nào tốt hơn để tìm RadioButton đã chọn cho một nhóm không? Đối với tôi, có vẻ như đoạn mã dưới đây không cần thiết. Khi bạn kiểm tra một RadioButton khác, nó sẽ biết cái nào cần bỏ chọn… vì vậy nó sẽ biết cái nào được chọn. Làm cách nào để lấy thông tin đó mà không cần thực hiện nhiều câu lệnh if (hoặc chuyển đổi).

     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
Mã bên dưới không biết cái nào cần bỏ chọn, nó chỉ lặp lại tất cả các điều khiển RadioButton bên dưới cùng một cha mẹ của điều khiển đã thay đổi và bỏ chọn cái đã kiểm tra trước đó.
João Angelo

1
Bạn đang sử dụng WinForms hoặc ASP.Net?
SLaks

Câu trả lời:


219

Bạn có thể sử dụng LINQ:

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

Lưu ý rằng điều này yêu cầu tất cả các nút radio trực tiếp trong cùng một vùng chứa (ví dụ: Bảng điều khiển hoặc Biểu mẫu) và chỉ có một nhóm trong vùng chứa. Nếu không đúng như vậy, bạn có thể tạo List<RadioButton>s trong hàm tạo của mình cho mỗi nhóm, sau đó viết list.FirstOrDefault(r => r.Checked).


Đó có nên được s.FirstOrDefaultthay vì list.FirstOrDefaulttrong đoạn thứ hai của câu trả lời của bạn?

@Phoenix: slà một đa nguyên, không phải là một tên biến.
SLaks

Câu trả lời xuất sắc, nhưng không thực sự trả lời câu hỏi chính của OP. Hãy xem câu trả lời của tôi.
D'Hag

cho bạn VB.NET guys, tôi sẽ giúp bạn tiết kiệm một chuyến đi đến công cụ chuyển đổi Telerik: Dim checkedButton = radConnections.Controls.OfType (Tất RadioButton) () FirstOrDefault (Function (r) r.Checked).
JoshYates1980

36

Bạn có thể nối CheckedEvents của tất cả các nút với một trình xử lý. Ở đó bạn có thể dễ dàng nhận được Hộp kiểm chính xác.

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

Nên này để thay thế - if (((RadioButton) người gửi) .Checked)
Frank Tzanabetis

1
Không có CheckedChanged trong RadioButton của WPF, bạn lấy nó từ đâu?
Murhaf Sousli

26

Đối với những người không có 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 muốn lấy RadioButton BY GROUP đã được kiểm tra. Trong khi câu trả lời của @SLaks là tuyệt vời, nó không thực sự trả lời câu hỏi chính của OP. Để cải thiện câu trả lời của @SLaks, chỉ cần thực hiện LINQ thêm một bước.

Đây là một ví dụ từ mã làm việc của riêng tôi. Theo WPF bình thường, RadioButtons của tôi được chứa trong mộtGrid (có tên là "myGrid") với một loạt các loại điều khiển khác. Tôi có hai nhóm RadioButton khác nhau trong Grid.

Để lấy RadioButton đã kiểm tra từ một nhóm cụ thể:

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

Nếu mã của bạn có khả năng không có nút RadioButton nào được kiểm tra, hãy sử dụng SingleOrDefault()(Nếu tôi không sử dụng các nút ba trạng thái, thì tôi luôn đặt một nút "IsChecked" làm lựa chọn mặc định.)


1
r.GroupName == "GroupName" và r.IsChecked thuộc các loại khác nhau (bool và bool?), bạn nên sử dụng r.IsChecked.Value, thuộc loại bool.
Mike

1
thử .Where(r => r.GroupName == "GroupName" && r.IsChecked == true)r.IsCheckedlà thuộc tính bool nullable.
Firnas

myGrid đề cập đến những gì ở đây.
Unnikrishnan

@Mike Bạn có thể cho biết "radioButtons" ở đây là gì không?
Bella Swan

1
@BellaSwan - hãy xem mã - bạn tạo danh sách tất cả các nút radio và gán nó cho một biến. Và sau đó, trên cùng một biến, bạn cần chạy lựa chọn Where và gán nó cho rbTarget.
Mike

5

Bạn có thể sử dụng sự kiện CheckedChanged cho tất cả các RadioButtons của mình. Sendersẽ là RadioButtons không được chọn và đã chọn.


1

Bạn có thể sử dụng phương thức Mở rộng để lặp lại bộ sưu tập RadioButton's Parent.Controls. Điều này cho phép bạn truy vấn các RadioButton khác trong cùng phạm vi. Sử dụng hai phương pháp mở rộng, bạn có thể sử dụng phương pháp đầu tiên để xác định xem bất kỳ RadioButtons nào trong nhóm được chọn hay không, sau đó sử dụng phương pháp thứ hai để chọn. Trường Thẻ RadioButton có thể được sử dụng để giữ một Enum để xác định từng RadioButton trong nhóm:

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

Đây là một kiểu sử dụng điển hình:

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

1

Ngoài hệ thống dây CheckedChangedEvent, người ta có thể sử dụng thuộc tính Điều khiển "Thẻ" để phân biệt giữa các nút radio ... một giải pháp thay thế (mã spaghetti) sẽ là thuộc tính "TabIndex"; P


nó có nghĩa là bạn có thể nhanh chóng sử dụng trường hợp chuyển đổi trên id nút radio đã chọn (sử dụng thuộc tính System.Windows.Forms.Control.Tag). Vui lòng không đánh giá thấp nếu bạn chỉ đơn giản là không hiểu phần bổ sung của tôi cho câu hỏi.
Binkan Salaryman

1

Đôi khi trong những tình huống như thế này, tôi nhớ tuổi trẻ của mình, khi Access là lựa chọn độc nhất của tôi và tôi có thể cho mỗi nút radio trong một nhóm giá trị riêng của nó.

Bí quyết của tôi trong C # là sử dụng thẻ để đặt giá trị và khi tôi thực hiện lựa chọn từ nhóm, tôi đọc giá trị của thẻ của nút radio đã chọn. Trong ví dụ này, directionGroup là nhóm mà tôi có bốn năm nút radio với "None" và "NE", "SE", "NW" và "SW" là các thẻ trên bốn nút radio còn lại.

Tôi đã chủ động sử dụng một nút để nắm bắt giá trị của nút đã chọn, bởi vì việc gán một trình xử lý sự kiện cho tất cả các sự kiện CHeckCHanged của các nút khiến MỖI nút kích hoạt, vì thay đổi một nút sẽ thay đổi tất cả. Vì vậy, giá trị của người gửi luôn là RadioButton đầu tiên trong nhóm. Thay vào đó, tôi sử dụng phương pháp này khi tôi cần tìm hiểu cái nào được chọn, với các giá trị tôi muốn truy xuất trong thuộc tính Thẻ của mỗi 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, tôi đã thử nghiệm và sử dụng điều này trong công việc của mình.

Joey


Chỉ sửa đổi kết quả 'FormatableString', tôi đã có thể sử dụng mã trong chương trình của mình. Tôi cũng không biết về Thẻ radioButton. Đây là cách câu trả lời nên được. Ngài tuyệt vời.
Unnikrishnan

0

nếu bạn muốn lưu lựa chọn vào tệp hoặc bất kỳ mục nào khác và gọi nó sau, đây là những gì tôi làm

string[] lines = new string[1];

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

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

sau đó gọi nó bằng

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

0

Nếu bạn muốn lấy chỉ mục của nút radio đã chọn bên trong một điều khiển, bạn có thể sử dụng phương pháp này:

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

Ví dụ sử dụng:

int index = getCheckedRadioButton(panel1);

Mã không được kiểm tra tốt, nhưng có vẻ như thứ tự chỉ mục là từ trái sang phải và từ trên xuống dưới, như khi đọc một văn bản. Nếu không tìm thấy nút radio, phương thức trả về -1.

Cập nhật: Hóa ra lần thử đầu tiên của tôi không thành công nếu không có nút radio bên trong điều khiển. Tôi đã thêm một khối thử và bắt để khắc phục điều đó và phương pháp này hiện có vẻ hoạt động.


0

GroupBox có một sự kiện Xác thực cho mục đích này, nếu bạn đang sử dụng 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

Đối với các nhà phát triển sử dụng 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.