简体   繁体   English

在C#中引发外部对象的事件

[英]Raising external object's events in C#

If actions is a Panel, am I able to raise the Click event of it's parent? 如果actions是Panel,我是否能够提升其父级的Click事件? I have this code at the moment, but the Click event isn't a method, so this code is invalid. 我目前有此代码,但Click事件不是方法,因此此代码无效。
Does anyone know how I can achieve this? 有谁知道我怎么能做到这一点?

actions.Click += delegate(object Sender, EventArgs e)
{
    ((Panel)Sender).Parent.Click();
}

It's not possible to raise a C# event directly from another class (even if it's public ). 不可能直接从另一个class引发C# event (即使它是public )。 You could provide a method (with a sufficient access modifier) that raises the event on your behalf and call that method in the other class . 您可以提供一个方法(具有足够的访问修饰符),代表您引发event并在另一个class调用该方法。

By the way, this is possible with reflection, but I consider that a dirty hack. 顺便说一句,这可以通过反思,但我认为这是一个肮脏的黑客。

Most types in the CLR that raises events has a protected On[EventName] method that takes care of raising the event. CLR中引发事件的大多数类型都有一个受保护的On [EventName]方法,它负责引发事件。 You can invoke this protected method "from the outside" using Reflection: 您可以使用Reflection“从外部”调用此受保护的方法:

 Control parent = ((Control)sender).Parent;
 Type parentType = parent.GetType();
 MethodInfo onClickMethod = parentType.GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic);

 onClickMethod.Invoke(parent, new object[] { e });

I implemented this using reflection and extension methods so that I can just invoke (in this case) a LinkLabel click event by just calling: 我使用反射和扩展方法实现了这一点,这样我只需调用以下方法就可以调用(在本例中)一个LinkLabel click事件:

var link = new LinkLabel()'
link.Text = "Some link";
link.click();

the click() method is an C# extension method: click()方法是一个C#扩展方法:

    public static void click(this LinkLabel linkLabel)
{
    var e = new LinkLabelLinkClickedEventArgs((LinkLabel.Link)(linkLabel.prop("FocusLink")));
    linkLabel.invoke("OnLinkClicked", e);
}

which uses another extension methods to: 它使用另一种扩展方法:

  • get a private property from the LinkLabel (needed to create the LinkLabelLinkClickedEventArgs object) 从LinkLabel获取私有属性(需要创建LinkLabelLinkClickedEventArgs对象)
  • invoke the OnLinkClicked method (which will fire the event 调用OnLinkClicked方法(将触发事件

Depending on what framework you are using its possible you don't have to manually invoke the click event on the parent, WPF and ASP.NET for example bubble events up the element tree. 根据您正在使用的框架,您不必手动调用父, WPFASP.NET上的click事件,例如元素树上的bubble事件。

If that's not an option you can do like Mehrdad suggests. 如果这不是一个选项,你可以像Mehrdad建议的那样做。

The only reason I can think of for why you would want to raise the Click event is if you are simulating user input. 我可以想到为什么你想提出Click事件的唯一原因是你是在模拟用户输入。 Are you working on an automated test driver or something like that? 您是在使用自动测试驱动程序还是其他类似的东西? If so, there may be better solutions than sullying the code with test-only auxiliary methods. 如果是这样,可能有更好的解决方案,而不是使用仅测试辅助方法来玷污代码。 This comes up first in google, I have no idea if it's any good. 在谷歌首先出现,我不知道它是否有任何好处。

If you're trying to do this as a kind of flow control in your application itself, I'd take a step back to see if this is the right thing to do at all - it kind of "smells bad". 如果你试图在你的应用程序本身作为一种流量控制来做这件事,我会退一步看看这是否是正确的做法 - 它有点“闻起来很糟糕”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM