2

(これまでのところ) チェックボックスのみを含む Windows フォームを作成しました。コンストラクターは 1 つのパラメーターを取ります: string[] attributes. このattributes配列の文字列ごとに、チェックボックスを作成します。

例えば:

string[] attributes = {
                          "Black",
                          "Red",
                          "Blue"
                      };
form1 = new MyForm(attributes);
form1.Show();

次のようにチェックボックスを作成します。

[ ] Black
[ ] Red
[ ] Blue

これはうまくいきます。次のステップは、次の動作を持つチェックボックス「すべてをチェック」を作成することです。「Check All」チェックボックスthisを参照するために使用します。

いつ:

  • ユーザーチェックthis: 他のすべてのチェックボックスがチェックされます。
  • User unchecks this: 他のすべてのチェックボックスがオフになります。
  • 他のすべてのチェックボックスは手動でチェックされます:thisあまりにもチェックされます.
  • すべてのチェックボックスがチェックされ、それらのいずれかがチェック解除されます。チェックも解除されthisます。

上記のルールをすべて実行できましたが、問題が発生し、それを修正する方法がわかりません。すべてのチェックボックスがオンになっていて、ユーザーが 1 つのチェックボックスをオフにすると、[すべてチェック] チェックボックスがオフになります。それも。「すべてチェック」チェックボックスがオフになったので、ユーザーが「すべてチェック」チェックボックスをオフにしたかのように、すべてのチェックボックスをオフにするuncheckイベントが自動的に呼び出されます。

CheckedChangedチェックボックスをオフにする別のチェックボックスを呼び出しているときに、チェックボックスを実行しないように指示する方法はありますか?

これが私のコードです(すべて手作業で書かれているため、ビジュアルスタジオデザイナーは使用していません):

using System;
using System.Drawing;
using System.Windows.Forms;

class MyForm
{
    public MyForm(string[] attributes)
    {
        SpawnControls(attributes);
    }

    private CheckBox[] m_attributes;
    private CheckBox m_all;

    private void SpawnControls(string[] attributes)
    {
        CheckBox dummy = new CheckBox();
        int nAttr = attributes.Length;

        m_attributes = new CheckBox[nAttr];
        for (int i = 0; i < nAttr; i++)
        {
            m_attributes[i] = new CheckBox();
            m_attributes[i].Text = attributes[i];
            m_attributes[i].Location = new Point(5, dummy.Height * i);
            m_attributes[i].CheckedChanged += attribute_CheckedChanged;
            Controls.Add(m_attributes[i]);
        }

        m_all = new CheckBox();
        m_all.Text = "Check All";
        m_all.Location = new Point(5, m_attributes[nAttr - 1].Bottom);
        m_all.CheckedChanged += all_CheckedChanged;
        Controls.Add(m_all);
    }

    private void attribute_CheckedChanged(object sender, EventArgs e)
    {
        if (((CheckBox)sender).Checked)
        {
            foreach (CheckBox cb in m_attributes)
            {
                if (cb.Checked == false)
                {
                    return;
                }
            }
            m_all.Checked = true;
        }
        else if (m_all.Checked)
        {
            m_all.Checked = false;
        }
    }

    private void all_CheckedChanged(object sender, EventArgs e)
    {
        if (m_all.Checked)
        {
            foreach (CheckBox cb in m_attributes)
            {
                cb.Checked = true;
            }
        }
        else
        {
            foreach (CheckBox cb in m_attributes)
            {
                cb.Checked = false;
            }
        }
    }
}
4

2 に答える 2

3

イベント ハンドラーの先頭で All_Check コントロールにフォーカスがあるかどうかを確認し、フォーカスがない場合はイベントを終了できます。

private void all_CheckedChanged(object sender, EventArgs e)
{

    if (!m_all.Focused)
     return ;

    if (m_all.Checked)
    {
        foreach (CheckBox cb in m_attributes)
        {
            cb.Checked = true;
        }
    }
    else
    {
        foreach (CheckBox cb in m_attributes)
        {
            cb.Checked = false;
        }
    }
}
于 2013-02-10T11:41:00.423 に答える
1

イベント ハンドラー ロジックが短絡する必要がある場合にフラグを立てるブール値のメンバー レベル変数を追加するか、サブスクライブを解除して最後に再サブスクライブすることができall_CheckedChangedますattribute_CheckedChanged

于 2013-02-10T11:29:19.637 に答える