1

基本的にイベントをアプリの JavaScript 部分にルーティングする、さまざまなイベントの共通ハンドラーを宣言したいと思います。私自身は JS/AS3 のバックグラウンドがあり、このようなことは比較的簡単に行うことができます。ただし、SilverLight と C# はかなり厳密に見えます。

計画は次のようになります。JSは、インスタンス化するクラス名と呼び出すメソッドを文字列引数として使用して、特別な[ScriptableMember]を呼び出します。[ScriptableMember]は次に、クラスのインスタンスを構築し、オプションで、そのインスタンスによって起動できるイベントをサブスクライブする必要があります。サブスクライブするイベントは、何らかの public static 構造体で公開されます。[ScriptableMember]は、その構造体からイベント プロパティを抽出し、単一のイベント ハンドラーでそれらすべてにサブスクライブする必要があります。共通の単一イベント ハンドラーは、C# イベントを JS イベントに変換する必要があります。

明らかに、ある種のファクトリ ロジックですべてを一般化し、自動化する必要があります。

これに関する大きな問題の 1 つは、デリゲートまたは EventArgs オブジェクトの型を事前に知ることができないことです。また、ケースごとにオーバーロードを作成するのは面倒だとわかっていたとしても。C# で一般的なイベント ハンドラーを定義する方法はありますか?

アップデート:

記述されたロジックを扱うコード スニペットを次に示します。

[ScriptableMember]
public void exec(string compName, string action, ScriptObject scriptObject)
{
    String compFQName;
    Type compClass; 
    object comp;    

    compFQName = "fully.qualified.name." + compName;

    compClass = Type.GetType(compFQName);

    if (compClass != null) {
        comp = Activator.CreateInstance(compClass);

        FieldInfo fieldInfo = compClass.GetField("dispatches", BindingFlags.Static | BindingFlags.Public);
        object[] dispatches = (object[])fieldInfo.GetValue(comp);

        if (dispatches != null) {
            foreach (string eventName in dispatches) {
                EventInfo eventInfo = compClass.GetEvent(eventName);
                Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, "OnComponentEvent");
                eventInfo.AddEventHandler(comp, handler);
            }                       
        }
    }

    // ...
}

そして、すべてのイベントをキャッチするイベント ハンドラーがあります。

public void OnComponentEvent(object sender, EventArgs args)
{
     // do something ...
}
4

1 に答える 1

3

EventArgsすべてのイベント引数は、クラスから継承する必要があります。このルールに従えば、次のようにハンドラーを宣言できます

public void GenericHandler(object sender, EventArgs e)

そしてそれを任意のイベントにサブスクライブします

編集: 前述のORマッパーのように、ハンドラーの署名が上記と比較できない場合は、イベントをサブスクライブした匿名メソッドから呼び出すことができます。次に例を示します。

public delegate void StupidEventHandler(int walueThatMustBeWrappedToEventArgs);
public event StupidEventHandler StupidEventOccured;

//....

{
    //....
    stupidClass.StupidEventOccured += delegate(int value) { handlerObject.GenericHandler(stupidClass, new StupidEventHandlerWrapper(value)); }
}

編集: 質問は異常な .NET 機能の使用法を示唆しているため、処理も異常です。あなたはこれをすべてにサブスクライブするので、発生する可能性のあるイベントの種類を知っておく必要があります。次に、次のように処理します。

public void GenericHandler(object sender, EventArgs e)
{
    if (e is MouseEventArgs)
    {
        var mouseArgs = e as MouseEventArgs;
        // .. process this case
    }
    else if (e is ....)
}

編集:

サブスクライブするには、これを試してください:

[ScriptableMember]
public void exec(string compName, string action, ScriptObject scriptObject)
{
    String compFQName;
    Type compClass; 
    object comp;    

    compFQName = "fully.qualified.name." + compName;

    compClass = Type.GetType(compFQName);

    if (compClass != null) {
        comp = Activator.CreateInstance(compClass);

        FieldInfo fieldInfo = compClass.GetField("dispatches", BindingFlags.Static | BindingFlags.Public);
        object[] dispatches = (object[])fieldInfo.GetValue(comp);

        if (dispatches != null) {
            foreach (string eventName in dispatches) {
                EventInfo eventInfo = compClass.GetEvent(eventName);

                EventHandler handlerMethod = OnComponentEvent;
                var handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, handlerMethod.Target, handlerMethod.Method);
                eventInfo.AddEventHandler(comp, handler);
            }                       
        }
    }

    // ...
}

なぜあなたのバージョンが動かないのかは、大きなミステリーです。

于 2012-08-19T16:09:25.520 に答える