2

標準のWinFormの適用ボタンは、読み込み時に無効になっています。他のコントロールの状態(チェックボックス、ラジオボックス、テキストボックスなど)が変更された場合は、有効にします。

したがって、すべてのコントロールのイベントを調べて、そこでボタンを有効にすることはできますが、グローバルイベントのように、もっと簡単な方法があるかどうかを知りたいと思います。

編集 明確にするために:私はすべてのコントロールで何かをする必要がない方法を探しています。後でコントロールを追加できるようにし、それらを気にする必要がないようにします...

4

2 に答える 2

2

あなたの編集に従って、私はあなたが望む機能を含むように私の答えを修正しました。

まず、次のような汎用イベントハンドラーが必要です。

void MyHandler(object obj, EventArgs e)
{
    button1.Enabled = true;
}

ここで、button1は有効にするボタンです。

Form.Controls次に、を反復処理するだけでなく、そこに含まれるコンテナタイプのコントロールも再帰的に実行する必要があります。いくつかの一般的なコンテナコントロールといくつかの基本的なデータ入力コントロールの処理を含めました。

void AddEvents(System.Windows.Forms.Control.ControlCollection Controls)
{
    foreach (Control c in Controls)
    {
        if (c is GroupBox)
        {
            AddEvents(((GroupBox)c).Controls);
        }
        else if (c is Panel)
        {
            AddEvents(((Panel)c).Controls);
        }
        //Expand this series of if...else... to include any 
        //other type of container control
        else if (c is TextBox)
        {
            ((TextBox)c).TextChanged += new EventHandler(MyHandler);
        }
        else if (c is RichTextBox)
        {
            ((RichTextBox)c).TextChanged += new EventHandler(MyHandler);
        }
        else if (c is CheckBox)
        {
            ((CheckBox)c).CheckedChanged += new EventHandler(MyHandler);
        }
        else if (c is DateTimePicker)
        {
            ((DateTimePicker)c).ValueChanged += new EventHandler(MyHandler);
        }
        //Expand this to include any other type of controls your form 
        //has that you need to add the event to
    }
}

ブロックの最初の部分は、が他のコントロールを含むタイプであるif elseかどうかを確認します。controlそうである場合は、その中に含まれているnewを使用してAddEventsメソッドを再帰的に呼び出します。System.Windows.Forms.Control.ControlCollectioncontrol

ブロックの2番目の部分は、if elseコントロールcのタイプをチェックして、正しいタイプに適切にキャストできるようにし、正しいイベントを利用できるようにします。この時点でコントロールタイプを判別できる場合は、前に作成した汎用イベントがハンドラーとして追加されます。

最後に、このメソッドを呼び出す必要があります。2つの最適な場所は、おそらくコンストラクターまたはForm.Loadイベントのいずれかになります。それを置くのに最適な場所は、特定の状況によって異なります。簡単にするためにコンストラクターを使用することにしました。これは次のようになります。

public Form1()
{
    InitializeComponent();
    AddEvents(this.Controls);
}

コントロールを繰り返し、汎用イベントハンドラーを追加するために必要なのはこれだけです。このコードは、私が作成した実際のプロジェクトからのものであり、適切な機能であることを確認するためにテストしました。

編集:私はまた、上にあるの内側の内側の内側の内側のsを使用してこれをテストしcontrolました。ここで、再帰を利用することの有用性が出てきます。ブロックを適切に設定している限り、ネストの正確な深さを知る必要はありません。ネストされたループを使用したり、正確な深さを知らなくても、必要なだけ深くなります。GroupBoxPanelGroupBoxPanelFormif...else...

EDIT2:補足として、このメソッドはより詳細なレベルでも使用できます。複数のGroupBoxコントロールがあり、「grpBox1」のコントロールにのみイベントハンドラーを追加したいとします。AddEvents(grpBox1.Controls)の代わりにを呼び出すことができます。AddEvents(this.Controls)これは、に含まれるコントロールにのみイベントハンドラーを適用しますgrpBox1

EDIT3: onemancatがコメントで指摘しているように、すべてのコントロールはプロパティを持つ基本クラスから継承するため、コントロールがaGroupBoxまたはなどであるかどうかを実際に確認する必要はありません。を言うことで他のコントロールが含まれているかどうかを簡単に確認できますが、反復するコンテナコントロールを選択したい状況では、私の例のようにタイプを確認する必要があります。このように細かくする必要がない場合は、カウントをチェックする方が理にかなっており、タイプチェックやキャストに煩わされることはありません。PanelControlControlsControlif (c.Controls.Count > 0) AddEvents(c.Controls);

于 2013-02-02T03:04:16.863 に答える
1

これがアプリケーションの一般的なテーマになる場合は、フォームのすべてのコントロールを再帰的に調べ、イベントハンドラーを接続する再利用可能なコードを作成できます。InitiaizeComponent();の直後に配置できます。

        // Programmatically wire up all Changed events to enable the button
        foreach (Control ctl in this.Controls)
        {
            if (ctl is CheckBox)
            {
                ((CheckBox)ctl).CheckedChanged += new EventHandler(Button_Enable);
            }
            else if (ctl is RadioButton)
            {
                ((RadioButton)ctl).CheckedChanged += new EventHandler(Button_Enable);
            }
            // Here, wire up all other control types you'd like the button to respond to
        }

次に、ハンドラーでボタンを有効にします。

void Button_Enable(object obj, EventArgs e)
{
    MyButton.Enabled = true;
}

多くのフォームでこのメソッドを呼び出して、ユーザーに一貫したUIを作成できます。このアプローチの利点は、フォームに新しいコントロールを追加するときに、変更イベントを有効になっているボタンに接続することを覚えておく必要がないことです。これは自動的に行われます。

于 2013-02-02T03:18:27.177 に答える