Gruptaki hangi Radyo düğmesi işaretlenir?


118

WinForms Kullanımı; Bir grup için işaretli RadioButton'ı bulmanın daha iyi bir yolu var mı? Bana öyle geliyor ki aşağıdaki kod gerekli olmamalı. Farklı bir RadioButton'ı işaretlediğinizde, hangisinin işaretini kaldıracağını bilir… bu yüzden hangisinin işaretlendiğini bilmelidir. Çok fazla if ifadesi (veya bir anahtar) yapmadan bu bilgileri nasıl alırım?

     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
Temeldeki kod hangisinin işaretini kaldıracağını bilmez, sadece değiştirilen denetimin aynı üst öğesinin altındaki tüm RadioButton denetimlerini yineler ve daha önce işaretlenmiş olanın işaretini kaldırır.
João Angelo

1
WinForms veya ASP.Net kullanıyor musunuz?
SLaks

Yanıtlar:


219

LINQ kullanabilirsiniz:

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

Bunun, tüm radyo düğmelerinin doğrudan aynı kapta (ör. Panel veya Form) olmasını ve kapsayıcıda yalnızca bir grup olmasını gerektirdiğine dikkat edin. Eğer durum bu değilse, kurucunuzda List<RadioButton>her grup için s yapabilir , sonra yazabilirsiniz list.FirstOrDefault(r => r.Checked).


Cevabınızın ikinci paragrafı s.FirstOrDefaultyerine bu mu olmalı list.FirstOrDefault?

@Phoenix: sbir değişken adı değil, çoğullaştırmadır.
SLaks

Mükemmel cevap, ancak OP'nin ana sorusuna gerçekten cevap vermedi. Cevabımı gör.
D'Hag

sizin için vb.net çocuklar, size Telerik dönüştürücüsüne bir gezi kaydedeceğim: Dim checkeredButton = radConnections.Controls.OfType (Of RadioButton) (). FirstOrDefault (Function (r) r.Checked)
JoshYates1980

36

Sen bağlayabilirsiniz CheckedEvents bir işleyicisi karşı tüm düğmelerin. Orada doğru Onay Kutusunu kolayca alabilirsiniz.

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

Bunun yerine bu olmalı - if (((RadioButton) gönderen) .Checked)
Frank Tzanabetis

1
WPF'nin RadioButton'unda CheckedChanged yok bunu nereden aldın?
Murhaf Sousli

26

LINQ olmayanlar için:

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, kontrol edilen RadioButton BY GROUP'u almak istedi. @SLaks'ın cevabı mükemmel olsa da, OP'nin ana sorusuna gerçekten cevap vermiyor. @SLaks'ın cevabını geliştirmek için LINQ'yu bir adım daha ileri götürmeniz yeterli.

İşte kendi çalışma kodumdan bir örnek. Normal WPF başına, RadioButton'larım Grid("myGrid" olarak adlandırılan) bir grup diğer denetim türüyle birlikte bulunur. Grid'de iki farklı RadioButton grubum var.

İşaretli RadioButton'ı belirli bir gruptan almak için:

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

Kodunuzun RadioButton'ların kontrol SingleOrDefault()edilme olasılığı yoksa, o zaman kullanın (Üç durumlu düğmeler kullanmıyorsam, varsayılan seçim olarak her zaman bir düğmeyi "IsChecked" olarak ayarlıyorum.)


1
r.GroupName == "GroupName" ve r.IsChecked farklı türdendir (bool ve bool?), bool türünde r.IsChecked.Value kullanmalısınız.
Mike

1
deneyin .Where(r => r.GroupName == "GroupName" && r.IsChecked == true)çünkü r.IsCheckednull yapılabilir bool özelliği.
Firnas

myGrid burada neyi ifade ediyor.
Unnikrishnan

@Mike Burada "radioButtons" ın ne olduğunu söyleyebilir misiniz?
Bella Swan

1
@BellaSwan - koda bir göz atın - tüm radyo düğmelerinin bir listesini oluşturur ve onu bir değişkene atarsınız. Ve sonra, aynı değişkende Where seçimini çalıştırmanız ve bunu rbTarget'a atamanız gerekir.
Mike

5

Tüm RadioButton'larınız için CheckedChanged olayını kullanabilirsiniz . Senderişaretlenmemiş ve işaretli RadioButtons olacaktır.


1

RadioButton'ın Parent.Controls koleksiyonunu yinelemek için bir Extension yöntemi kullanabilirsiniz. Bu, aynı kapsamdaki diğer RadioButton'ları sorgulamanıza olanak tanır. İki uzantı yöntemini kullanarak, gruptaki herhangi bir RadioButton öğesinin seçilip seçilmediğini belirlemek için ilkini kullanabilir, ardından ikinci seçeneği kullanarak seçimi elde edebilirsiniz. RadioButton Etiketi alanı, gruptaki her RadioButton öğesini tanımlamak için bir Enum tutmak için kullanılabilir:

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

İşte tipik bir kullanım modeli:

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

1

CheckedChangedEvent kablolamasına ek olarak, radyo düğmeleri arasında ayrım yapmak için Kontroller "Etiketi" özelliği kullanılabilir ... bir (spagetti kodu) alternatifi "TabIndex" özelliği olabilir; P


Bu, seçilen radyo düğmesi kimliğinde hızlı bir şekilde geçiş durumlarını kullanabileceğiniz anlamına gelir (System.Windows.Forms.Control.Tag özelliğini kullanarak), soruya yaptığım eklemeyi anlamıyorsanız lütfen puan vermeyin.
Binkan Salaryman

1

Bazen böyle durumlarda gençliğimi özlüyorum, Access seçim zehrim iken ve bir gruptaki her radyo düğmesine kendi değerini verebiliyordum.

C #'daki hack'im, değeri ayarlamak için etiketi kullanmaktır ve gruptan bir seçim yaptığımda, seçilen radyo düğmesinin etiketinin değerini okurum. Bu örnekte, directionGroup , diğer dört radyo düğmesindeki etiketler olarak "Yok" ve "NE", "SE", "NW" ve "SW" olan dört beş radyo düğmesine sahip olduğum gruptur.

İşaretlenen düğmenin değerini yakalamak için proaktif olarak bir düğme kullandım, çünkü tüm düğmelerin CHeckCHanged olayına bir olay işleyicisi atamak EACH düğmesinin ateşlenmesine neden oluyor çünkü birini değiştirmek hepsini değiştiriyor. Dolayısıyla gönderenin değeri her zaman gruptaki ilk RadioButton'dur. Bunun yerine, her RadioButton öğesinin Tag özelliğinde almak istediğim değerlerle hangisinin seçildiğini bulmam gerektiğinde bu yöntemi kullanıyorum.

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

Bilginize, bunu işimde test ettim ve kullandım.

Joey


Yalnızca 'FormatableString' sonucunu değiştirerek, kodu programımda kullanabildim. Ayrıca radioButton Tag'dan haberdar değildim. Cevaplar böyle olmalı. Yüce Efendim.
Unnikrishnan

0

seçimi dosyaya veya başka bir yere kaydetmek ve daha sonra aramak istiyorsanız, işte yapacağım

string[] lines = new string[1];

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

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

o zaman onunla ara

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

0

Bir kontrolün içindeki seçili radyo düğmesinin dizinini almak istiyorsanız şu yöntemi kullanabilirsiniz:

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

Örnek kullanım:

int index = getCheckedRadioButton(panel1);

Kod o kadar iyi test edilmemiştir, ancak bir metni okurken olduğu gibi, dizin sırası soldan sağa ve yukarıdan aşağıya doğru görünüyor. Radyo düğmesi bulunmazsa, yöntem -1 değerini döndürür.

Güncelleme: Kontrolün içinde radyo düğmesi yoksa ilk denemem işe yaramadı. Bunu düzeltmek için bir dene ve yakala bloğu ekledim ve yöntem şimdi işe yarıyor gibi görünüyor.


0

WinForms kullanıyorsanız, GroupBox bu amaç için Validated olayına sahiptir.

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 kullanan geliştiriciler için


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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.