c# 仅使用方法名称(文本)向事件添加侦听器
c# Adding a listener to Event with only the method name (text)
我正在尝试使用反射将 class 中的方法添加到事件中。这是我的设置。
- 有一个 class 带有 keyPressDown 和 keyPressUp 方法。我在这个 class 中也有一个事件。 keyPressDown 和 keyPressUp 将触发订阅它的任何方法(如果有的话)。
这些额外的方法是控制RGB发光二极管。一种方法可以使颜色闪烁,另一种方法可以使颜色褪色,等等。
我可以像myEventKeyUp这样订阅事件 += myClass.MethodA;
我的问题是,我将用户想要的配置存储在数据库中。所以我唯一能想到的就是将方法名称存储为文本并使用反射将其添加到事件处理程序中。
代码示例:
Class我的Class
public event delegateKeyDown keyDownEvent;
public event delegateKeyUp keyUpEvent;
public void KeyUp()
{
joystick.SetBtn(false, 1, vJoyButtonID);
if (keyUpEvent != null) keyUpEvent();
}
public void KeyDown()
{
joystick.SetBtn(true, 1, vJoyButtonID);
// IF WE HAVE ANY LISTENERS THEN FIRE THEM
if (keyDownEvent != null) keyDownEvent();
}
public void MethodA()
{
// DO SOMeTHING HERE
}
主窗体
button.keyDownEvent += button.SetRandomColor;
button.keyUpEvent += button.TurnOff;
我需要做的是:
button.keyUpEvent += MyClass.GetType().GetMethod("MethodA");
我知道你不能用反射做我想做的事,我读到我可以使用反射来获取包含事件处理程序的委托,并通过这种方式添加它,但我不确定(或对此不清楚)。
按照 Jim W 的 link,这里有一个工作示例:
using System;
using System.Reflection;
internal class Program
{
private static void Main()
{
var foo = new Foo();
var fooType = foo.GetType();
var eventInfo = fooType.GetEvent("Bar");
var methodInfo = fooType.GetMethod("OnBar", BindingFlags.Static | BindingFlags.Public);
eventInfo.AddEventHandler(foo, Delegate.CreateDelegate(eventInfo.EventHandlerType, methodInfo));
foo.RaiseBar();
Console.ReadKey();
}
}
public class Foo
{
public delegate void BarHandler(object sender, BarEventArgs args);
public event BarHandler Bar;
public void RaiseBar()
{
Bar(this, new BarEventArgs());
}
public static void OnBar(object sender, BarEventArgs args)
{
Console.WriteLine(args.Guid);
}
}
public class BarEventArgs : EventArgs
{
public Guid Guid => Guid.NewGuid();
}
感谢两位的帮助。在显示的两个示例之间,我能够理解这一点。我做了一个函数来处理事件设置如下:
private void SetupEventHandlers(RGBButton button,string EventName, string MethodName)
{
// THIS SETS UP THE EVENT HANDLER THAT WILL FIRE ANY ADDITION
// ACTIONS THE USER COULD WANT WHEN A BUTTON IS PRESSED OR RELEASED.
var p = button;
var eventInfo = p.GetType().GetEvent(EventName);
var methodInfo = typeof(RGBButton).GetMethod(MethodName);
try
{
// TRY TO SUBSCRIBE TO OUR KEYUP OR KEYDOWN EVENT
Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, p, methodInfo);
eventInfo.AddEventHandler(p, handler);
}
catch (Exception)
{
// MOST LIKELY COULDN'T FIND THE METHOD WE ARE TRYING TO FIRE
throw new System.InvalidOperationException("Failed to find method: " + MethodName + "', which is registered as an Event Subscriber.");
}
}
这使我可以通过一个函数将任何给定名称(存储在数据库中)添加到 class 中的一个事件(几个不同的事件)。 var P = 按钮是一个 class,它定义了我的 RGB Led 街机按钮。 class 包含按下按钮时触发的事件。
我正在尝试使用反射将 class 中的方法添加到事件中。这是我的设置。
- 有一个 class 带有 keyPressDown 和 keyPressUp 方法。我在这个 class 中也有一个事件。 keyPressDown 和 keyPressUp 将触发订阅它的任何方法(如果有的话)。
这些额外的方法是控制RGB发光二极管。一种方法可以使颜色闪烁,另一种方法可以使颜色褪色,等等。
我可以像myEventKeyUp这样订阅事件 += myClass.MethodA;
我的问题是,我将用户想要的配置存储在数据库中。所以我唯一能想到的就是将方法名称存储为文本并使用反射将其添加到事件处理程序中。
代码示例:
Class我的Class
public event delegateKeyDown keyDownEvent;
public event delegateKeyUp keyUpEvent;
public void KeyUp()
{
joystick.SetBtn(false, 1, vJoyButtonID);
if (keyUpEvent != null) keyUpEvent();
}
public void KeyDown()
{
joystick.SetBtn(true, 1, vJoyButtonID);
// IF WE HAVE ANY LISTENERS THEN FIRE THEM
if (keyDownEvent != null) keyDownEvent();
}
public void MethodA()
{
// DO SOMeTHING HERE
}
主窗体
button.keyDownEvent += button.SetRandomColor;
button.keyUpEvent += button.TurnOff;
我需要做的是: button.keyUpEvent += MyClass.GetType().GetMethod("MethodA");
我知道你不能用反射做我想做的事,我读到我可以使用反射来获取包含事件处理程序的委托,并通过这种方式添加它,但我不确定(或对此不清楚)。
按照 Jim W 的 link,这里有一个工作示例:
using System;
using System.Reflection;
internal class Program
{
private static void Main()
{
var foo = new Foo();
var fooType = foo.GetType();
var eventInfo = fooType.GetEvent("Bar");
var methodInfo = fooType.GetMethod("OnBar", BindingFlags.Static | BindingFlags.Public);
eventInfo.AddEventHandler(foo, Delegate.CreateDelegate(eventInfo.EventHandlerType, methodInfo));
foo.RaiseBar();
Console.ReadKey();
}
}
public class Foo
{
public delegate void BarHandler(object sender, BarEventArgs args);
public event BarHandler Bar;
public void RaiseBar()
{
Bar(this, new BarEventArgs());
}
public static void OnBar(object sender, BarEventArgs args)
{
Console.WriteLine(args.Guid);
}
}
public class BarEventArgs : EventArgs
{
public Guid Guid => Guid.NewGuid();
}
感谢两位的帮助。在显示的两个示例之间,我能够理解这一点。我做了一个函数来处理事件设置如下:
private void SetupEventHandlers(RGBButton button,string EventName, string MethodName)
{
// THIS SETS UP THE EVENT HANDLER THAT WILL FIRE ANY ADDITION
// ACTIONS THE USER COULD WANT WHEN A BUTTON IS PRESSED OR RELEASED.
var p = button;
var eventInfo = p.GetType().GetEvent(EventName);
var methodInfo = typeof(RGBButton).GetMethod(MethodName);
try
{
// TRY TO SUBSCRIBE TO OUR KEYUP OR KEYDOWN EVENT
Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, p, methodInfo);
eventInfo.AddEventHandler(p, handler);
}
catch (Exception)
{
// MOST LIKELY COULDN'T FIND THE METHOD WE ARE TRYING TO FIRE
throw new System.InvalidOperationException("Failed to find method: " + MethodName + "', which is registered as an Event Subscriber.");
}
}
这使我可以通过一个函数将任何给定名称(存储在数据库中)添加到 class 中的一个事件(几个不同的事件)。 var P = 按钮是一个 class,它定义了我的 RGB Led 街机按钮。 class 包含按下按钮时触发的事件。