19

どのような状況下でもこれを達成できるでしょうか?

私の現在の状況は次のとおりです。

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 ライブラリは、コントロール内のメッセージ ハンドラーと呼び出しイベントを使用して常にこれを行います。他の誰かが他の/より良いアイデアを持っていますか?

4

4 に答える 4

31

イベントを呼び出すパブリック メソッドを追加するだけです。Microsoft は、 Clickイベントを公開するコントロールのPerformClickなどの一部のイベントに対して既にこれを行っています。

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();
}
于 2008-09-20T11:52:34.383 に答える
10

C# の event キーワードは、デリゲートの宣言を変更します。これにより、デリゲートへの直接の割り当てが防止され (イベントでは += と -= のみを使用できます)、クラス外からのデリゲートの呼び出しが防止されます。

したがって、コードを次のように変更できます。

public class CustomGUIElement
{
...
    public MouseEventHandler Click;
    // etc, and so forth.
...
}

次に、このようにクラスの外部からイベントを呼び出すことができます。

myCustomGUIElement.Click(sender,args);

欠点は、クラスを使用するコードが、次のようなコードで登録済みのハンドラーを非常に簡単に上書きできることです。

myCustomGUIElement.Click = null;

Click デリゲートがイベントとして宣言されている場合、これは許可されません。

于 2008-09-21T20:56:26.657 に答える
1

外部から実行できるようにしたいコードは、メソッドでラップする必要があります。そのメソッドは、イベントが行うことを何でも実行できます。また、そのイベントは代わりにそのメソッドを呼び出します。

于 2008-09-20T11:52:23.963 に答える