所有クラスの外部から C# イベントを呼び出しますか?
-
01-07-2019 - |
質問
どのような状況でもこれを達成することは可能でしょうか?
私の現在の状況は次のとおりです。
public class CustomForm : Form
{
public class CustomGUIElement
{
...
public event MouseEventHandler Click;
// etc, and so forth.
...
}
private List<CustomGUIElement> _elements;
...
public void CustomForm_Click(object sender, MouseEventArgs e)
{
// we might want to call one of the _elements[n].Click in here
// but we can't because we aren't in the same class.
}
}
私の最初の考えは、次のような関数を持つことでした。
internal enum GUIElementHandlers { Click, ... }
internal void CustomGUIElement::CallHandler(GUIElementHandler h, object[] args) {
switch (h) {
case Click:
this.Click(this, (EventArgs)args[0]);
break;
... // etc and so forth
}
}
恐ろしく醜い汚物だが、うまくいくはずだ...もっとエレガントな解決策があるはずですが?.NET ライブラリは、コントロールのメッセージ ハンドラーと呼び出しイベントを使用してこれを常に実行します。他に何か他の/より良いアイデアがある人はいますか?
解決
イベントを呼び出すためのパブリック メソッドを追加するだけです。Microsoft は、次のようないくつかのイベントでこれをすでに行っています。 パフォームクリック を公開するコントロールの場合、 クリック イベント。
public class CustomGUIElement
{
public void PerformClick()
{
OnClick(EventArgs.Empty);
}
protected virtual void OnClick(EventArgs e)
{
if (Click != null)
Click(this, e);
}
}
次に、サンプルのイベント ハンドラー内で次の操作を実行します。
public void CustomForm_Click(object sender, MouseEventArgs e)
{
_elements[0].PerformClick();
}
他のヒント
C# のevent キーワードはデリゲートの宣言を変更します。これにより、デリゲートへの直接割り当てが防止され (イベントでは += と -= のみを使用できます)、クラスの外部からのデリゲートの呼び出しが防止されます。
したがって、コードを次のように変更できます。
public class CustomGUIElement
{
...
public MouseEventHandler Click;
// etc, and so forth.
...
}
次に、次のようにクラスの外部からイベントを呼び出すことができます。
myCustomGUIElement.Click(sender,args);
欠点は、このクラスを使用するコードは、次のようなコードで登録されているハンドラーを簡単に上書きできることです。
myCustomGUIElement.Click = null;
Click デリゲートがイベントとして宣言されている場合、これは許可されません。
外部から実行できるようにしたいコードはメソッドでラップする必要があります。そのメソッドは、イベントが実行することをすべて実行できるようになり、イベントは代わりにそのメソッドを呼び出すことになります。
所属していません StackOverflow