質問

私はここで自分自身を追い詰めてしまいました。

親から継承する一連の UserControl があります。これには、処理を簡略化するためのいくつかのメソッドとイベントが含まれているため、ほぼ同じコードを何行も記述する必要はありません。あなたのように。親には他のコントロールは含まれません。

私がやりたいのは、親の UserControl にイベント ハンドラーを 1 つだけ用意し、親コントロールのみが実行できること (つまり、親で定義されているイベントを条件付きで呼び出すこと) を実行することです。次に、このイベント ハンドラーを子コントロールのすべての入力ボックスに接続すると、子コントロールは入力を解析し、そのイベントをスローするかどうかを親コントロールに伝えるタスクを整理します。素晴らしくクリーンで、繰り返しのコピー&ペーストのコードはありません(私にとってはこれです) いつも バグが発生します)。

ここで私の質問です。Visual Studioは、私が半分ほど賢くなっていると考えており、「メソッドのチェックレディネス」[親のイベントハンドラー]は、このクラスがすでにメソッドを定義しているため、イベントの方法ではないと警告しています。はい、ビジュアルスタジオ、 それがポイントです. 。私 欲しい 子クラスによってスローされたイベントのみを処理するイベント ハンドラーを用意する必要があります。その唯一の役割は、コードを 1 行も記述せずに子クラスを接続できるようにすることです。これらの追加のハンドラーは必要ありません。必要な機能はすべて、子がユーザー入力を処理するときに自然に呼び出されます。

Visual Studio がなぜ今この問題について不満を言い始めたのかはわかりません (以前はそうさせてくれていたのに)、またこれを解消する方法もわかりません。できれば、CheckReadiness を呼び出すだけのメソッドを定義せずに実行したいと考えています。この警告は何が原因で発生しているのでしょうか。1 時間前には警告が表示されなかったのに、今は警告が表示されるようになっているのはなぜでしょうか。すべての子クラスで小さなハンドラーを作成せずに警告を表示しないようにするにはどうすればよいでしょうか?

役に立ちましたか?

解決

親メソッド virtual を宣言し、子クラスでオーバーライドして呼び出します。

base.checkReadyness(sender, e);

子クラス内から(またはその派生)。これにより、親イベント ハンドラーを呼び出す前に特定のエラー チェック コードを実行したい場合など、将来の設計の進化が可能になります。このようなイベント ハンドラーをコントロールごとに何百万も記述する必要はなく、1 つだけ記述するだけで、すべてのコントロールをこのイベント ハンドラーにフックし、親のイベント ハンドラーを呼び出すことができます。

私が注意したことの 1 つは、このコードがすべて DLL 内に配置されている場合、DLL 内からイベント ハンドラーを呼び出そうとするとパフォーマンスが低下する可能性があるということです。

他のヒント

私もこれに出会ったばかりですが、すべてが正しく行われているように感じることに同意します。メソッド virtual の宣言は、せいぜい回避策であり、解決策ではありません。

行われている内容は有効です。コントロールは派生クラス内にのみ存在し、派生クラスはそのコントロールのイベントの 1 つにイベント ハンドラーをアタッチしています。イベントを処理するメソッドが基本クラスで定義されているという事実は、ここにもそこにも存在せず、イベントにバインドする時点で使用可能です。イベントが 2 回アタッチされているわけではありません。イベントを処理するメソッドがどこに定義されているかが問題です。

間違いなく、これは仮想メソッドではありません。このメソッドを派生クラスによってオーバーライドできるようにしたくありません。非常にイライラしますが、私の意見では、dev-studio のバグです。

以前のバージョンの VS ではイベント ハンドラーを「継承」できたため、私もこの問題を経験しました。したがって、メソッドをオーバーライドすることなく私が見つけた解決策は、フォームの初期化フェーズのどこかにイベント ハンドラーを割り当てるだけです。私の場合、コンストラクターで実行しました(OnLoad() も同様に機能すると確信しています)。

    public MyForm()
    {
        InitializeComponent();
        btnOK.Click += Ok_Click;
    }

...Ok_Click ハンドラーが基本フォームに存在する場所。思考の糧。

Merus が最初に提起したまさにその問題に遭遇したところですが、他の回答投稿者と同様に、VS (現在 Visual C# 2010 Express を使用しています) がベースでイベント ハンドラーを定義することに反対する理由がまったくわかりません。クラス。私が応答を投稿している理由は、基底クラスのコードを、派生クラスが (本質的に空の) イベント ハンドラーで単に呼び出す保護されたメソッドにすることで問題を回避する過程で、基底クラスの名前をリファクタリング変更したためです。クラスメソッドを開発し、VSデザイナーが文句を言わなくなったことに気づきました。つまり、イベント ハンドラー登録の名前が変更され (そのため、イベント ハンドラーに ControlName_EventName という名前を付ける VS デザイナーの規則には従わなくなりました)、これで条件を満たすように見えました。次に、適切な VS イベントに名前を入力して、派生クラス コントロールに対して (名前が変更された) 基本イベント ハンドラーを登録しようとすると、デザイナーは派生クラスに新しいイベント ハンドラーを作成し、その後それを削除し、派生クラス コントロールは登録されたままになりました。基本クラス (イベント ハンドラー) メソッドに追加します。ご想像のとおり、C# は私たちがやりたいことを正当に実行します。デザイナーのイベント ハンドラー命名規則に従った場合、それを気に入らないのは VS デザイナーだけです。デザイナーがそのように働く必要はないと思います。とにかく、続ける時間です。

イベントがすでに親クラスで定義されている場合は、子クラスで再度配線する必要はありません。これにより、イベントが 2 回発生します。

これが起こっているかどうかを確認してください。HTH:)

MSDN のこの記事は良い出発点となります。 Visual Basic .NET を使用したイベント ハンドラーのオーバーライド. 。を見てください。 Handles 句が派生クラスで問題を引き起こす仕組み セクション。

親クラスでメソッドを virtual として宣言し、派生クラスでそれをオーバーライドして追加の機能を追加できるのはなぜでしょうか?

これがイベント ハンドラーであることを忘れて、子クラスで適切な通常のメソッドのオーバーライドを実行してください。

以下は、いくつかの類似した形式で呼び出される基本メソッドを取得するために行ったことです。それぞれのメソッドには、一般的なものにいくつかの追加機能があります。

        protected override void OnLoad(EventArgs e)
    {
        try
        {
            this.SuspendLayout();
            base.OnLoad(e);

            foreach (Control ctrl in Controls)
            {
                Button btn = ctrl as Button;
                if (btn == null) continue;

                if (string.Equals(btn.Name, "btnAdd", StringComparison.Ordinal))
                    btn.Click += new EventHandler(btnAdd_Click);
                else if (string.Equals(btn.Name, "btnEdit", StringComparison.Ordinal))
                    btn.Click += new EventHandler(btnEdit_Click);
                else if (string.Equals(btn.Name, "btnDelete", StringComparison.Ordinal))
                    btn.Click += new EventHandler(btnDelete_Click);
                else if (string.Equals(btn.Name, "btnPrint", StringComparison.Ordinal))
                    btn.Click += new EventHandler(btnPrint_Click);
                else if (string.Equals(btn.Name, "btnExport", StringComparison.Ordinal))
                    btn.Click += new EventHandler(btnExport_Click);
            }

正しい固定ボタン名の使用が省略される可能性は、継承されたハンドラーを手動で配線しない可能性と私には同じように思えます。

VS Designer のコードをまったくスキップするには、this.DesignMode をテストする必要がある場合がありますが、チェックを入れなくても問題なく動作することに注意してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top