我想创建一个方法,将事件作为参数,并向其添加eventHandler以正确处理它。像这样:
我有两件事:
public event EventHandler Click;
public event EventHandler Click2;
现在我想将特定事件传递给我的方法(伪代码):
public AttachToHandleEvent(EventHandler MyEvent)
{
MyEvent += Item_Click;
}
private void Item_Click(object sender, EventArgs e)
{
MessageBox.Show("lalala");
}
ToolStripMenuItem tool = new ToolStripMenuItem();
AttachToHandleEvent(tool.Click);
有可能吗?
我注意到这段代码工作正常,并返回到我的项目,并注意到当我传递在我的类中声明的事件时,它可以工作,但是当我从其他类传递事件时它仍然无效。
我得到的是这个错误:
活动 'System.Windows.Forms.ToolStripItem.Click' 只能出现在左侧 + =或 - =
答案 0 :(得分:24)
我的原始答案适用于定义该事件的类中,但您已经更新了您的问题,以反映您希望从定义类之外完成此操作,所以我已经打败了它。
只有定义事件的类才能引用事件使用的隐式委托变量。在该课程之外,您只能通过add
和remove
访问+=
和-=
方法。这意味着你不能直接做你所要求的。但是,您可以使用功能方法。
class A{
public event EventHandler Event1;
public void TriggerEvent1(){
if(Event1 != null)
Event1(this, EventArgs.Empty);
}
}
class B{
static void HandleEvent(object o, EventArgs e){
Console.WriteLine("Woo-hoo!");
}
static void AttachToEvent(Action<EventHandler> attach){
attach(HandleEvent);
}
static void Main(){
A a = new A();
AttachToEvent(handler=>a.Event1 += handler);
a.TriggerEvent1();
}
}
答案 1 :(得分:5)
我是这样做的:
public AttachToHandleEvent(Object obj, string EventName)
{
EventInfo mfi = obj.GetType().GetEvent(EventName);
MethodInfo mobj = mfi.GetAddMethod();
mobj.Invoke(obj, new object[] { Item_Click});
}
private void Item_Click(object sender, EventArgs e)
{
MessageBox.Show("lalala");
}
ToolStripMenuItem tool = new ToolStripMenuItem();
AttachToHandleEvent(tool "Click");
谢谢大家的建议。没有你的帮助,这个解决方案无法完成。
答案 2 :(得分:2)
只需撰写tool.Click += Item_Click;
编辑:来自MSDN“只能从声明它们(它)的类或结构中调用事件”。所以你要做的就是不可能。你能详细说明你的需求吗?为什么要将事件作为参数传递?
答案 3 :(得分:2)
这是不可能的。如果符合您的需要,您可以使用代理而不是事件。
答案 4 :(得分:1)
delegate void doIt(object sender, object data);
event doIt OnDoIt;
void add(doIt theDel)
{
OnDoIt += theDel;
}
void doIt1(object a, object b)
{
}
void doIt2(object a, object b)
{
}
void add()
{
add(doIt1);
add(doIt2);
}
答案 5 :(得分:0)
你的问题表明你有一些错误的机制: 你无法通过活动!
您最有可能希望将函数作为参数传递,因此调用方法将在某个时刻调用其他方法。在技术方面,这是一个代表。我建议使用已定义的Action类。这是一个示例代码段:
void MyFunction (string otherArguments, Action onFinished){
...
if (onFinished != null)
onFinished.Invoke();
}
关于这一点的好处是,在调用MyFunction时,您可以使用内联语法声明Action:
MyFunction("my other argument", ()=>{
///do stuff here, which will be execuded when the action is invoked
});
答案 6 :(得分:0)
我这样传递函数/方法(而不是事件):
class A
{
public void something()
{
var myAction =
new Action<object, object>((sender, evArgs) => {
MessageBox.Show("hiii, event happens " + (evArgs as as System.Timers.ElapsedEventArgs).SignalTime);
});
B.timer(myAction);
}
}
class B
{
public static void timer( Action<object, System.Timers.ElapsedEventArgs> anyMethod)
{
System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.Elapsed += new System.Timers.ElapsedEventHandler(anyMethod);
myTimer.Interval = 2000;
myTimer.Start();
}
}
答案 7 :(得分:0)
使用面向对象的解决方案更新此问题。
您可以创建一个为您处理的对象,而不是使用 Action<EventHandler>
来注册事件
public class AEvent
{
private readonly A aInstance;
private AEvent(A instance) {
aInstance = instance;
}
public void Add(EventHandler eventHandler)
=> a.Event1 += eventHandler;
public void Remove(EventHandler eventHandler)
=> a.Event1 -= eventHandler;
public EventHandler Invoke => aInstance.Event1;
}
然后像这样使用该对象:
static void Main(){
A a = new A();
AEvent aEvent = new AEvent(A)
aEvent.Add(handler);
a.Invoke();
}