我想声明各种事件的通用处理程序,它基本上会将事件路由到应用程序的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 ...
}
每个事件参数都必须继承自EventArgs
类。如果您遵循此规则,则只需像
public void GenericHandler(object sender, EventArgs e)
并订阅任何活动
编辑:就像 O. R. 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);
}
}
}
// ...
}
为什么你的版本不起作用是一个很大的困惑。