0

相互に排他的なチェックボックスを作成しようとしています。

Windowsフォームには2つのチェックボックスがあります。CheckBox1がチェックされている場合、CheckBox2はチェックされていないはずです。CheckBoxesのCheckedChangedイベントを処理することでこれを達成しようとしましたが、無限ループに入りました。

以下の私のコードスニペット。

Private Sub chkBox1_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles chkBox1.CheckedChanged
    If chkBox2.CheckState = CheckState.Checked Then
        chkBox2.CheckState = CheckState.Unchecked
    End If
    If chkBox1.CheckState = CheckState.Unchecked Then
        chkBox1.CheckState = CheckState.Checked
    End If
End Sub

Private Sub chkBox2_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles chkBox2.CheckedChanged
    If chkBox1.CheckState = CheckState.Checked Then
        chkBox1.CheckState = CheckState.Unchecked
    End If
    If chkBox2.CheckState = CheckState.Unchecked Then
        chkBox2.CheckState = CheckState.Checked
    End If   
End Sub

誰かがこれに対する解決策を持っていますか?

編集 ここでラジオボタンを使用することは想定していません。

4

5 に答える 5

2

関連するすべてのチェックボックスボタンに同じイベントハンドラーを使用し、静的ローカル変数を使用して再入力から保護します

Private Sub chkBox_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles chkOnlyMyArea.CheckedChanged 
     Static inCheck as Boolean 
     if inCheck = true then 
         Exit Sub
     end if
     inCheck = true
     chkBox1.CheckState = CheckState.UnChecked    
     chkBox2.CheckState = CheckState.UnChecked    
     CheckBox c = CType(sender, CheckBox)
     c.CheckState = CheckState.Checked    
     inCheck = false
End Sub 
于 2012-07-17T08:27:08.837 に答える
2

チェックされた変更を台無しにしましたif。ハンドラーのそれぞれがそれ自体を起動しているため、無限ループになります。これは機能するはずです:

Private Sub chkBox1_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles chkBox1.CheckedChanged
    If chkBox1.CheckState = CheckState.Checked And chkBox2.CheckState = CheckState.Checked Then
        chkBox2.CheckState = CheckState.Unchecked
    End If
    If chkBox1.CheckState = CheckState.Unchecked And chkBox2.CheckState = CheckState.Unchecked Then
        chkBox2.CheckState = CheckState.Checked
    End If
End Sub


Private Sub chkBox2_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles chkBox2.CheckedChanged
    If chkBox2.CheckState = CheckState.Checked And chkBox1.CheckState = CheckState.Checked Then
        chkBox1.CheckState = CheckState.Unchecked
    End If
    If chkBox2.CheckState = CheckState.Unchecked And chkBox1.CheckState = CheckState.Unchecked Then
        chkBox1.CheckState = CheckState.Checked
    End If   

End Sub

これにより、間接的な再帰が回避されます

于 2012-07-17T08:36:29.127 に答える
1

3つ以上のチェックボックスがあり、それらを相互に排他的にする必要がある場合でも、後でさらにいくつか追加することがわかっているので、次のようにします。

 public class ObjectGroup
{
    public string ObjectName;
    public int GroupID;

    public ObjectGroup(int groupID, string objectName)
    {
        GroupID = groupID;
        ObjectName = objectName;
    }
}

フォーム定義:

private List<ObjectGroup> ObjectGroups;

フォームの読み込み:

//Set up checkbox groups
ObjectGroups = new List<ObjectGroup>();
ObjectGroups.Add(new ObjectGroup(1, "chStatic"));
ObjectGroups.Add(new ObjectGroup(1, "chNonStatic"));

そして、フォーム本体で:

private void chNonStatic_CheckedChanged(object sender, EventArgs e)
{
    SetCheckboxState(sender as CheckBox);
}

private void chStatic_CheckedChanged(object sender, EventArgs e)
{
    SetCheckboxState(sender as CheckBox);
}

この関数は、ヘルパークラスまたはフォーム自体に存在できます。

private void SetCheckboxState(CheckBox original)
    {
        var thisName = original.Name;
        var isChecked = original.Checked;
        //Find the object collection to which this control belongs
        var thisObject = (from q in ObjectGroups where q.ObjectName == thisName select q).FirstOrDefault();
        if (thisObject == null) return;
        var otherObjects = (from q in ObjectGroups where q.GroupID == thisObject.GroupID && q.ObjectName != thisName select q.ObjectName).ToList();
        foreach (var o in otherObjects)
        {
            CheckBox obj = this.Controls.Find(o, true).FirstOrDefault() as CheckBox;
            if (obj != null)
            {
                if (isChecked && obj.Checked) obj.Checked = false;
            }
        }
    }
于 2018-08-14T11:49:40.310 に答える
0

私が見つけた最も簡単な方法(2つ以上のチェックボックスで機能します)は、チェックを設定する前に、他のチェックボックスがチェックされていないかどうかをテストすることです。これにより、無限ループが強制終了されます。私はこれが古い投稿であることを知っていますが、この方法は3つ以上の排他的なチェックボックスを示しています。

Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
    If CheckBox1.Checked = True Then
        CheckBox2.Checked = False
        CheckBox3.Checked = False
    ElseIf CheckBox2.Checked = False And CheckBox3.Checked = False Then
        CheckBox1.Checked = True
    End If
End Sub

Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
    If CheckBox2.Checked = True Then
        CheckBox1.Checked = False
        CheckBox3.Checked = False
    ElseIf CheckBox1.Checked = False And CheckBox3.Checked = False Then
        CheckBox2.Checked = True
    End If
End Sub

Private Sub CheckBox3_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox3.CheckedChanged
    If CheckBox3.Checked = True Then
        CheckBox1.Checked = False
        CheckBox2.Checked = False
    ElseIf CheckBox1.Checked = False And CheckBox2.Checked = False Then
        CheckBox3.Checked = True
    End If
End Sub
于 2014-12-28T22:18:26.373 に答える
0

このcheckchangedハンドラーをグループボックスのすべてのチェックボックスに追加します。単純。

Private Sub ToggleCheckBoxOnEntry(sender As Object, e As EventArgs)
    Static CurrentlySelectedbox As CheckBox

    If CType(sender, CheckBox).Checked Then
        CurrentlySelectedbox = sender
    End If

    For Each cntrl As CheckBox In grpVentMode.Controls
        If cntrl.Checked AndAlso cntrl.Name <> CurrentlySelectedbox.Name Then
            cntrl.Checked = False
        End If
    Next

End Sub
于 2015-03-13T21:30:49.403 に答える