簡體   English   中英

選中組中的哪個單選按鈕?

[英]Which Radio button in the group is checked?

使用窗體; 有沒有更好的方法來為一個組找到選中的 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;
     }

你可以使用 LINQ:

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

請注意,這要求所有單選按鈕都直接位於同一個容器(例如,面板或表單)中,並且容器中只有一組。 如果不是這種情況,您可以在構造函數中為每個組創建List<RadioButton> ,然后編寫list.FirstOrDefault(r => r.Checked)

您可以針對一個處理程序連接所有按鈕的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;
    }
}

對於那些沒有 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;
}

OP 希望按組獲得選中的 RadioButton。 雖然@SLaks 的回答非常好,但它並沒有真正回答 OP 的主要問題。 要改進@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”設置為默認選擇。)

您可以對所有 RadioButton 使用CheckedChanged事件。 Sender將是未選中和選中的 RadioButton。

有時在這種情況下,我會懷念我的青春,那時 Access 是我的毒葯,我可以為組中的每個單選按鈕賦予自己的價值。

我在 C# 中的技巧是使用標簽來設置值,當我從組中進行選擇時,我會讀取所選單選按鈕的標簽值。 在這個例子中, directionGroup是我有四個五個單選按鈕的組,其中“None”和“NE”、“SE”、“NW”和“SW”作為其他四個單選按鈕上的標簽。

我主動使用一個按鈕來捕獲選中按鈕的值,因為將一個事件處理程序分配給所有按鈕的 CHeckCHanged 事件會導致每個按鈕觸發,因為更改一個會更改所有按鈕。 所以 sender 的值始終是組中的第一個 RadioButton。 相反,當我需要找出哪個被選中時,我會使用此方法,以及我想在每個 RadioButton 的 Tag 屬性中檢索的值。

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

僅供參考,我已經在我的工作中測試並使用了它。

喬伊

您可以使用擴展方法來迭代 RadioButton 的 Parent.Controls 集合。 這允許您查詢同一范圍內的其他 RadioButton。 使用兩種擴展方法,您可以使用第一種來確定是否選擇了組中的任何 RadioButton,然后使用第二種來獲取選擇。 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;

除了 CheckedChangedEvent 接線之外,還可以使用 Controls“Tag”屬性來區分單選按鈕......(意大利面條代碼)替代方法是“TabIndex”屬性;P

如果您想將選擇保存到文件或任何其他文件並稍后調用,請執行以下操作

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;

如果要獲取控件內所選單選按鈕的索引,可以使用以下方法:

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 塊來解決這個問題,現在該方法似乎有效。

如果您使用的是 WinForms,則 GroupBox 具有用於此目的的 Validated 事件。

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

對於使用 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

另一個嘗試 - 使用事件 lambda 表達式

在表單初始化時,可以將單個事件處理程序分配給組框中RadioButton類型的所有控件,並使用 .tabIndex 或 .tag 屬性來標識更改時選中的選項。

通過這種方式,您可以一次性訂閱每個單選按鈕的任何事件

int priceOption = 0;
foreach (RadioButton rbtn in grp_PriceOpt.Controls.OfType<RadioButton>())
{
    rbtn.CheckedChanged += (o, e) =>
    {
        var button = (RadioButton)o;
        if (button.Checked)
        {
            priceOption = button.TabIndex;
        }
    };
}

由於事件僅分配給單選按鈕,因此沒有實現發送者的類型檢查。

還要注意,當我們循環所有按鈕時,這可能是分配數據屬性、更改文本等的完美時機。

處理此問題的一種簡單方法是為每個單選按鈕捕獲 CheckedChanged 事件,並讓每個單選按鈕在其容器的 Tag 字段中設置它們的值。 然后,當您准備好閱讀單擊了哪個單選按鈕時,只需使用容器的 Tag 字段即可。

    private void rbUnread_CheckedChanged(object sender, EventArgs e)
    {
        if (rbUnread.Checked)
            pnlStatus.Tag = 1;
    }
    private void rbRead_CheckedChanged(object sender, EventArgs e)
    {
        if (rbRead.Checked)
            pnlStatus.Tag = 2;
    }
    private void rbUnfinished_CheckedChanged(object sender, EventArgs e)
    {
        if (rbUnfinished.Checked)
            pnlStatus.Tag = 3;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM