0

私は c# を使用して Windows フォーム アプリケーションを構築しています。多くのカスタム ユーザー コントロールを構築しており、GUI はこれらのユーザー コントロールの組み合わせです。問題は、メイン フォームからこのユーザー コントロールのイベントを設定すると、イベントが発生しないことですが、コントロール自体からそのイベントを設定し、このコントロール内のすべてのアイテムのイベントハンドラーをそのイベントハンドラーに設定すると、正常に動作し、コントロールをラップした限り、イベントとイベントハンドラーを設定するために深く行く必要があります、実際にはこれ「私はそれを望んでいない」より多くのオーバーヘッドがかかります。元:

メインフォームには、ユーザーコントロールである「患者」という名前のコントロールがあります。メインフォームからこのコントロールのクリックイベントを設定すると、発生しません

しかし、患者ユーザー コントロールの定義に移動し、カスタム イベントとイベント ハンドラーを定義すると、すべて問題ありません。

public event EventHandler PatientCliecked;

private void PatientClicked()
{
    if (this.PatientCliecked != null)
    this.PatientCliecked(new object(), new EventArgs());
}

private void ProcessPatientClickedEvent(object sender, EventArgs e)
{
    PatientClicked();
}

私の質問は、それを行う他の方法はありますか、それとも.NETのロジックですか??

4

2 に答える 2

1

UserControl は、Control クラスから Click イベントを継承します。確かに発火する可能性はありますが、そうなる可能性は高くありません。ユーザーは、代わりに UserControl 内のコントロールをクリックします。また、UserControl サーフェス全体を他のコントロールで覆った場合は、決して起動しません。

Click イベントを自分用にリダイレクトするだけです。独自のイベントを宣言することによって、すでに実験したもの。これは必須ではありません。代わりに次のようにすることができます。

private void PatientClicked()
{
    OnClick(this, EventArgs.Empty);
}

名前が On で始まり、イベントと同じ名前を持つすべてのメソッドと同様に、これは Click イベントを発生させます。

于 2013-09-17T11:59:57.457 に答える
0

先に行って撃ちます。

があるとしましょうUserControl。次のように見えるとします。

ここに画像の説明を入力

ここで、存在する 4 つの異なるコントロール ( 、 、 、および 自体) に対して次のハンドラーを作成しClickたとします。ButtonListViewRadioButtonUserControl

public partial class UserControl1 : UserControl {

    public UserControl1() {
        InitializeComponent();
    }

    private void radioButton1_Click(object sender, EventArgs e) {
        MessageBox.Show("RadioButton");
    }
    private void listView1_Click(object sender, EventArgs e) {
        MessageBox.Show("ListView");
    }
    private void button1_Click(object sender, EventArgs e) {
        MessageBox.Show("Button");
    }
    private void UserControl1_Click(object sender, EventArgs e) {
        MessageBox.Show("UserControl");
    }

}

私が言っていることを明確にするために、.designer.csファイルの次のサブセットを確認してください。

...
this.radioButton1.Click += new System.EventHandler(this.radioButton1_Click);
...
this.button1.Click += new System.EventHandler(this.button1_Click);
...
this.listView1.Click += new System.EventHandler(this.listView1_Click);
...
this.Click += new System.EventHandler(this.UserControl1_Click);
...

以下のアファメーションを検討してください。

この青い領域をクリックすると:

ここに画像の説明を入力

ハンドラーが呼び出され、UserControl1_Click"UserControl" メッセージ ボックスが表示されます。

この他の青い領域をクリックすると:

ここに画像の説明を入力

「listView1_Click」ハンドラーが呼び出され、「ListView」メッセージ ボックスが表示されますが、「 UserControl」メッセージ ボックスは表示されません。

これは、残りの両方のコントロールであるボタンにも当てはまります。

ここに画像の説明を入力

そしてラジオボタン:

ここに画像の説明を入力

UserControl最終的なコンテナーの観点から を見て、イベントが表示され、そのイベント ハンドラーを追加している場合、ここに示されているイベント ハンドラーClickの動作とまったく同じ動作を期待する必要があります。UserControl1_Click

必要に応じて、子コントロールの特定のセット用のカスタム イベント ハンドラーを作成し、外部の世界にあるハンドラーのサブスクリプションとサブスクリプション解除をそのイベントとの間で単純にリダイレクトすることができます。

public event EventHandler SmallButtonsClick {
    add {
        this.radioButton1.Click += value;
        this.button1.Click += value;
    }
    remove {
        this.radioButton1.Click -= value;
        this.button1.Click -= value;
    }
}

public event EventHandler LargeStuffClick {
    add {
        this.listView1.Click += value;
    }
    remove {
        this.listView1.Click -= value;
    }
}

または、すべての子コントロールと UserControl 自体に動的な方法でハンドラーをサブスクライブすることもできます

public event EventHandler AnythingClick {
    add {
        this.Click += value;
        foreach (var child in this.Controls)
            child.Click += value;
    }
    remove {
        this.Click -= value;
        foreach (var child in this.Controls)
            child.Click -= value;
    }
}

そして、周囲の世界からそれを使用するだけです:

UserControl1 someControl = new UserControl1();
someControl.AnythingClick += (sender, e) => MessageBox.ShowMessage("tadaaa!");
于 2013-09-17T12:15:40.030 に答える