Raising external object's events in C#
Asked Answered
M

5

8

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();
}
Margit answered 26/4, 2009 at 7:6 Comment(0)
I
10

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.

Insalivate answered 26/4, 2009 at 7:10 Comment(2)
Could I create a new Panel class the inherits the old one, and then add a method to raise the Click event?Margit
Sorry it's not a dirty trick, it has its place in AoP so that you don't write NotifyPropertyChanged for every property in your class and in the process cluttering your model.Gramarye
D
5

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 });
Deadman answered 26/4, 2009 at 7:26 Comment(0)
B
2

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
Brachio answered 7/2, 2010 at 23:58 Comment(0)
B
1

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.

Betony answered 26/4, 2009 at 7:19 Comment(0)
S
1

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".

Sanderson answered 26/4, 2009 at 20:20 Comment(1)
I'm trying to get the Click event to bubble up, I'm not using WPF, so it doesn't occur automatically.Margit

© 2022 - 2024 — McMap. All rights reserved.