How to get event name in event handler [duplicate] - c#

This question already has answers here:
How to get event name in called method
(2 answers)
Closed 8 years ago.
I'm curious if is possible to get event name in event handler?
I'm pretty sure, that it's possible, can you help me find solution?
Ex:
public class Boy
{
public event EventHandler Birth;
public event EventHandler Die;
}
public class Mother
{
public Mother()
{
Boy son = new Boy();
son.Birth += son_Handler;
son.Die += son_Handler;
}
void son_Handler(object sender, EventArgs e)
{
// how to get event name (Birth/Die)?
throw new NotImplementedException();
}
}

I'm curious if is possible to get event name in event handler?
No, it's not. The event handler is just a method. It could be invoked directly, not in the context of any event.
What you could do is have:
public Mother()
{
Boy son = new Boy();
son.Birth += (sender, e) => Handler("Birth", sender, e);
son.Die += (sender, e) => Handler("Die", sender, e);
}
void Handler(string description, object sender, EventArgs e)
{
Log("I'm in the {0} event", description);
throw new NotImplementedException();
}

You need to inherit EventArgs class and add necessary fields.
class MyArgs : EventArgs
{
public string What { get; set; }
}
delegate void MyHandler(object sender, MyArgs e);
. . .
var myEvent = birthEvent;
if (myEvent != null)
myEvent(new MyArgs { What = "Birth"};

Related

Cancelling event invoking sequence in previous invoked method

I made a derived class from Button control class. When I use the control, I need to make to be prevented from invocation in some situation. The situation is already defined in the derived class, myClick function. I guessed there is a way like setting e.Cancel = true, but I can't. Can you give a simple suggestion to solve this task?
public class SButton : Button
{
public SButton() : base()
{
Click += new System.EventHandler(myClick);
}
private void myClick(object sender, EventArgs e)
{
if( meHandsome )
{
// here I want to prevent no more event invocation!
}
}
}
public partial class UTeachAdvanced : DevExpress.XtraEditors.XtraUserControl
{
private void UTeachAdvanced_Load(object sender, EventArgs e)
{
SButton btn = new SButton();
Controls.Add(btn);
btn.Click += new EventHandler(delegate(object sender, EventArgs args)
{
Console.Write("ugly");
}
}
}
The situation is already defined in the derived class.
The Click event raises by Control.OnClick method. To prevent raising Click event, you can override OnClick and call base.OnClick only if the criteria to prevent the click is not true:
public class SampleButton : Button
{
protected override void OnClick(EventArgs e)
{
if(!criteriaToPrevent)
base.OnClick(e);
}
}

Wiring and unwiring events in C# with arguments

i am trying to make use of events in C#. I am really new to events. Following is my code.
public void GetVoltage(Object objName, Object objCcaVar)
{
DynamicSystemVariable mysys = new DynamicSystemVariable("VTS::M9_Ch3", "AvgVoltage");
mysys.ValueChanged += (sender, e) => mysys_ValueChanged(sender, e, ""); ;
}
void mysys_ValueChanged(object sender, EventArgs e,String name)
{
DynamicSystemVariable mysys = (DynamicSystemVariable)sender;
Output.WriteLine(mysys.GetValue().ToString());
Output.WriteLine("System Variable Changed");
if (_unwireEvent)
mysys.ValueChanged -= mysys_ValueChanged;
}
It gives me following error on the line where i am unwiring it.
No overload for 'mysys_ValueChanged' matches delegate 'System.EventHandler'
I will appreciate if somebody can help me out.
Thanks
Tom
Instead of sending name as a seperate parameter, create a new class deriving from EventArgs and add name parameter to this class as a property. Something like;
public class MyEventArgs : EventArgs
{
public string Name {get; private set;}
public MyEventArgs(EventArg e, string name)
{
this.Name = name;
}
}
mysys.ValueChanged += mysys_ValueChanged(sender, new MyEventArgs("some name"));
Also do not forget to change the signiture of mysys_ValueChanged.
Note that this is just a workaround, and proper way is defining a new delegate which uses MyEventArgs and using a seperate handling method instead of an inline method.
The problem is that you haven't register mysys_ValueChanged. You registered an anonymous method.
You have to change your code to:
public void GetVoltage(Object objName, Object objCcaVar)
{
DynamicSystemVariable mysys = new DynamicSystemVariable("VTS::M9_Ch3", "AvgVoltage");
mysys.ValueChanged += this.OnEvent;
}
private void OnEvent(object sender, EventArgs e)
{
mysys_ValueChanged(sender, e, "");
}
void mysys_ValueChanged(object sender, EventArgs e,String name)
{
DynamicSystemVariable mysys = (DynamicSystemVariable)sender;
Output.WriteLine(mysys.GetValue().ToString());
Output.WriteLine("System Variable Changed");
if (_unwireEvent)
mysys.ValueChanged -= OnEvent; // Unregister what you've registered.
}
EDIT
Having new input it could be solved that way:
public void GetVoltage(Object objName, Object objCcaVar)
{
DynamicSystemVariable mysys = new DynamicSystemVariable("VTS::M9_Ch3", "AvgVoltage");
EventHandler<EventArgs> handler = null;
handler = (s, e) => mysys_ValueChanged(s, e, "", handler);
mysys.ValueChanged += handler;
}
void mysys_ValueChanged(object sender, EventArgs e, String name, EventHandler<EventArgs> handler)
{
DynamicSystemVariable mysys = (DynamicSystemVariable)sender;
Output.WriteLine(mysys.GetValue().ToString());
Output.WriteLine("System Variable Changed");
if (_unwireEvent)
mysys.ValueChanged -= handler; // Unregister what you've registered.
}
I haven't tried it but I think this could work - but in my opinion it's hacked.

Creating custom event for hiding a control not working

Here is my code in my userControl
public partial class UserControlHomeScreen : UserControl
{
public event EventHandler SomethingHappened;
public void DoSomething()
{
EventHandler handler = SomethingHappened;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
public void HandleEvent(object sender, EventArgs args)
{
MessageBox.Show("Wafak.");
}
public UserControlHomeScreen()
{
InitializeComponent();
}
private void btnAverageDailyBal_Click(object sender, EventArgs e)
{
this.Tag = 0;
this.Hide();
}
private void btnComputeTransferPricing_Click(object sender, EventArgs e)
{
this.Tag = 1;
this.Hide();
}
}
And here is my code in my main form
private void HomeScreen()
{
uHomeScreen = new UserControlHomeScreen();
uHomeScreen.Dock = DockStyle.Fill;
//uHomeScreen.Disposed += new EventHandler(uHomeScreen_Disposed);
uHomeScreen.SomethingHappened += new EventHandler(uHomeScreen_SomethingHappened);
panelMain.Controls.Add(uHomeScreen);
}
void uHomeScreen_SomethingHappened(object sender, EventArgs e)
{
MessageBox.Show("throw new NotImplementedException();");
}
What i want to happen is that when the usercontrol is hidden i want to fire an event in my main form but does not work, what am i missing? please help. thanks!
Your naming convention for event raiser (DoSomething) is confusing, your code doesn't call DoSomething (or raise the event SomethingHappened), so how could it fire for you? Add the following code in your user control class:
//override the OnVisibleChanged
protected override void OnVisibleChanged(EventArgs e){
if(!Visible) DoSomething();
}

How to work with delegates and event handler for user control

I have created a user control that contains a button.
I am using this control on my winform which will be loaded at run time after fetching data from database.
Now I need to remove a row from a datatable on the Click event of that button.
The problem is that how do I capture that event in my form. Currently it goes in that user control's btn click event defination.
You can create your own delegate event by doing the following within your user control:
public event UserControlClickHandler InnerButtonClick;
public delegate void UserControlClickHandler (object sender, EventArgs e);
You call the event from your handler using the following:
protected void YourButton_Click(object sender, EventArgs e)
{
if (this.InnerButtonClick != null)
{
this.InnerButtonClick(sender, e);
}
}
Then you can hook into the event using
UserControl.InnerButtonClick+= // Etc.
It's not necessary to declare a new delegate. In your user control:
public class MyControl : UserControl
{
public event EventHandler InnerButtonClick;
public MyControl()
{
InitializeComponent();
innerButton.Click += new EventHandler(innerButton_Click);
}
private void innerButton_Click(object sender, EventArgs e)
{
if (InnerButtonClick != null)
{
InnerButtonClick(this, e); // or possibly InnerButtonClick(innerButton, e); depending on what you want the sender to be
}
}
}
Just modernizing ChéDon's answer, here is how you can do it in 2018:
public class MyControl : UserControl
{
public event EventHandler InnerButtonClick;
public MyControl()
{
InitializeComponent();
innerButton.Click += innerButton_Click;
}
private void innerButton_Click(object sender, EventArgs e)
{
InnerButtonClick?.Invoke(this, e);
//or
InnerButtonClick?.Invoke(innerButton, e);
//depending on what you want the sender to be
}
}

How to subscribe to other class' events in C#?

A simple scenario: a custom class that raises an event. I wish to consume this event inside a form and react to it.
How do I do that?
Note that the form and custom class are separate classes.
public class EventThrower
{
public delegate void EventHandler(object sender, EventArgs args) ;
public event EventHandler ThrowEvent = delegate{};
public void SomethingHappened() => ThrowEvent(this, new EventArgs());
}
public class EventSubscriber
{
private EventThrower _Thrower;
public EventSubscriber()
{
_Thrower = new EventThrower();
// using lambda expression..could use method like other answers on here
_Thrower.ThrowEvent += (sender, args) => { DoSomething(); };
}
private void DoSomething()
{
// Handle event.....
}
}
Inside your form:
private void SubscribeToEvent(OtherClass theInstance) => theInstance.SomeEvent += this.MyEventHandler;
private void MyEventHandler(object sender, EventArgs args)
{
// Do something on the event
}
You just subscribe to the event on the other class the same way you would to an event in your form. The three important things to remember:
You need to make sure your method (event handler) has the appropriate declaration to match up with the delegate type of the event on the other class.
The event on the other class needs to be visible to you (ie: public or internal).
Subscribe on a valid instance of the class, not the class itself.
Assuming your event is handled by EventHandler, this code works:
protected void Page_Load(object sender, EventArgs e)
{
var myObj = new MyClass();
myObj.MyEvent += new EventHandler(this.HandleCustomEvent);
}
private void HandleCustomEvent(object sender, EventArgs e)
{
// handle the event
}
If your "custom event" requires some other signature to handle, you'll need to use that one instead.

Categories

Resources