简体   繁体   中英

Raising external object's events in C#

If actions is a Panel, am I able to raise the Click event of it's parent? I have this code at the moment, but the Click event isn't a method, so this code is invalid.
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 ). 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 .

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. You can invoke this protected method "from the outside" using 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:

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

the click() method is an C# extension method:

    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)
  • invoke the OnLinkClicked method (which will fire the event

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.

If that's not an option you can do like Mehrdad suggests.

The only reason I can think of for why you would want to raise the Click event is if you are simulating user input. 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".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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