我意识到有很多问题涉及通过反思来举办活动,但是我还没有能够找到以下答案[我怀疑答案是"没有&# 34]:
鉴于"标准"事件的声明,有没有办法通过引用字符串文字来引发事件。
例如,伪代码:
Dim eventName As String = "TestEvent"
RaiseEvent eventName
显然,这不会奏效。
我可以使用
获取事件处理程序/多播委托的类型Me.GetType.GetEvent("TestEvent").GetAddMethod.GetParameters(0).Name
// "TestEventEventHandler
但我无法在页面对象上找到此实例来调用.GetInvocationList
这与此问题类似:How can I get an actual EventHandler delegate instance from an event in VB.NET?
然而,我在这里特别关注从字符串中提出事件。
修改
vb.net / webforms环境中有一些不同之处。根据我对接受的答案的评论,由于(我相信)代码隐藏模型的性质,它不可能返回与Me.GetType()
中的事件对应的字段,如在运行时期间{ {1}}指的是.aspx文件中的继承类,而不是.aspx.vb文件中的类。
实际上,这意味着我必须使用Me
来查找字段。
第二件不同的事情,虽然与最终答案无关,但是在c#中你可以直接引用事件处理程序MulticastDelegate,在vb.net中你不能 - 或者至少要做因此,您必须使用intellisense不支持的未记录的功能,如下所示:How can I get an actual EventHandler delegate instance from an event in VB.NET?
答案 0 :(得分:1)
您可以在类型实例上调用GetField
,然后在返回的FieldInfo
上致电GetValue()
。这是一个例子(在c#中,因为我不会说vb.net)
class Foo
{
public event EventHandler Bar;
}
class Program
{
static void Main(string[] args)
{
var foo = new Foo();
foo.Bar += FooOnBar;
var ev = (MulticastDelegate)foo.GetType().GetField("Bar", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(foo);
if (ev != null)
{
foreach (var del in ev.GetInvocationList())
{
del.Method.Invoke(del.Target, new object[] {foo, new EventArgs()});
}
}
Console.ReadLine();
}
private static void FooOnBar(object sender, EventArgs eventArgs)
{
Console.WriteLine("Invoked!");
}
}
答案 1 :(得分:0)
我遇到的问题是迭代Me.GetType()
的字段集合没有返回“TestEvent”字段。我做了一些进一步的挖掘,并意识到这是因为事件是在“代码隐藏”类中声明的,例如:myPageName.aspx.vb,但是在运行时,此代码是从继承的“设计”类调用的,例如myPageName。 ASPX。
此博客文章指出,即使使用BindingFlags.FlattenHierarchy
,.GetType.GetField()
也不会从继承的类返回私有静态字段。 http://bobpowell.net/eventsubscribers.aspx
结果,解决方案是使用Me.GetType.BaseType.GetField("TestEvent")
,并从那里使用Tejas Sharma所描述的技术。此答案中提供了此技术的vb.net示例:How to Attach the Events of an Original Object to a Deep Copied Clone