1

我想为各种事件声明通用处理程序,这基本上会将事件路由到应用程序的 JavaScript 部分。我自己是为 JS/AS3 背景而来的,在这种情况下,这样的事情做起来相对简单。SilverLight 和 C# 看起来相当严格。

计划如下,JS 将调用一个特殊的[ScriptableMember]并带有要实例化的类名和要调用的方法,作为字符串参数。[ScriptableMember]然后必须构造该类的实例并可选择订阅可由该实例触发的事件。要订阅的事件将在某种公共静态结构中公开。[ScriptableMember]必须从该结构中提取事件属性并使用单个事件处理程序订阅所有这些属性。通用的单个事件处理程序应该将 C# 事件转换为 JS 事件。

显然,一切都应该在某种工厂逻辑中通用化和自动化。

一个大问题是我无法事先知道委托或 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 Mapper,如果您的处理程序的签名与上面所说的无法比较,您可以从订阅您的事件的匿名方法调用它,例如:

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 回答