Handle multiple events with the same event handler - c#

I've got a notification, and I want to dismiss it with a click anywhere on the screen, or any keypress. Currently, I've got two methods that look like this
private void Dismiss(object sender, MouseEventArgs e)
{
if(dismissable && dismissSeconds<=0)
{
FadeOut();
}
}
private void Dismiss(object sender, KeyEventArgs e)
{
if (dismissable && dismissSeconds <= 0)
{
FadeOut();
}
}
I know that if the two objects send the same args type you can just select the same event handler in the properties window but since one returns KeyEventArgs and the other returns MouseEventArgs, that doesn't work.
If I'm not using the args anyway though, can I get rid of this duplicate code? Or am I going to confuse the designer if I start messing about?

Just extract the code to a new method that you call from the two event handlers:
private void Dismiss(object sender, MouseEventArgs e)
{
Dismiss();
}
private void Dismiss(object sender, KeyEventArgs e)
{
Dismiss();
}
private void Dismiss()
{
if (dismissable && dismissSeconds <= 0)
{
FadeOut();
}
}
Note that you could declare a single event handler, by specifying EventArgs as the parameter type:
private void Dismiss(object sender, EventArgs e)
{
if (dismissable && dismissSeconds <= 0)
{
FadeOut();
}
}
This way, the handler would be compatible with both events. However I wouldn't recommend doing that, because I think it's cleaner to keep things clearly separated. If someday you need to do something slightly different for the mouse event and the keyboard event, you will have more refactoring to do if you used a single handler.

Related

How to call an event handler from another method

Given the following event handler code:
private void image1_MouseDown(object sender, MouseButtonEventArgs e)
{
///////////
}
How can I call it from another method:
private void timerTick(object sender, EventArgs e)
{
image1_MouseDown(object, e); // error
}
Event handlers are regular methods like any others.
The reason you can't call it like you're trying to do, is because the MouseDown event takes a MouseButtonEventArgs instance, while the Tick event of timers take the base class EventArgs.
You'll need to create a new instance of MouseButtonEventArgs, but then you'll need to initialize it with a device, and other event data.
A better option would be to refactor the body of the MouseDown event handler to a method taking individual parameters, which you can then call without having to create a MouseButtonEventArgs instance.
private void image1_MouseDown(object sender, MouseButtonEventArgs e)
{
this.ProcessImageMouseDown(e.ChangedButton, e.ButtonState, e.GetPosition(sender as FrameworkElement));
}
private void timerTick(object sender, EventArgs e)
{
this.ProcessImageMouseDown(MouseButton.Left, MouseButtonState.Pressed, new Point(10d, 20d));
}
private void ProcessImageMouseDown(MouseButton button, MouseButtonState state, System.Windows.Point position)
{
// Do actual processing here.
}

How to call a Control's event handler? Get EventArgs value C#

I am trying to call a OnCellEditEnding event from another event,
private void BillsTableRecords_OnCellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
// do stuff here
}
My issue is I don't know how to pass the DataGridCellEditEndingEventArgs into the method, i.e. the e in the below method obviously gives an error as it is referencing RoutedEventArgs not DataGridCellEditEndingEventArgs.
private void BillsRecordsCheckBox_OnChecked(object sender, RoutedEventArgs e)
{
BillsTableRecords_OnCellEditEnding(sender, e);
}
So how do obtain the value from DataGridCellEditEndingEventArgs so that I can pass the value in the method? Please note that the DataGrid cell with be selected at this point so it will contain a value.
I wouldn't recommend this approach. Event handlers are to be called by events; their signature does not really fit for a standalone call. In case you execute business code in your event handler, it is also not good design, because your event handlers are UI code, which should be separated from business code.
The best way to go here is to create a dedicated method that does what you want and call it from both event handlers:
private void DoStuff(/* add the parameters you need*/) {
//do stuff
}
private void BillsTableRecords_OnCellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
DoStuff();
}
private void BillsRecordsCheckBox_OnChecked(object sender, RoutedEventArgs e)
{
DoStuff();
}
try that
private void BillsRecordsCheckBox_OnChecked(object sender, RoutedEventArgs e)
{
BillsTableRecords_OnCellEditEnding(sender, new DataGridCellEditEndingEventArg());
}
If you want to keep the arguments from the RoutedEventArgs, add them to the constructor of DataGridCellEditEndingEventArg

Clicking on a PictureBox

I would like to know how I can make a PictureBox click using the Text box .
private void textBox2_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
// I wanna a method to click on PictureBox1 here
}
}
Calling an event from another event is a bad idea. (In fact, calling a user driven event in your code is always a bad idea).
If you want to run some code, put it in its own method and call it from each event.
private void textBox2_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
MyPictureBoxCode();
}
}
private void PictureBox_Click(object sender, EventArgs e)
{
MyPictureBoxCode();
}
private void MyPictureBoxCode()
{
//common code
}
The PictureBox Click event and the Textbox2 Click event must be tied in from your designer.cs.

Make a timer perform bidder00_TextChanged Event

I am trying to figure out how to make it that when my timer ticks, it performs a bidder00_TextChanged, or something like that.
Is this even possible to do? and if it isn't, is there any other way to do it?
I tried to search Google for it but i didn't get any results, if you find anything that i missed please post it here.
I don't really have any code but here it is:
private void bidder00_TextChanged(object sender, EventArgs e)
{
if (bidder00.Text == addbidder1.Text)
{
bidBtn1.PerformClick();
}
}
That is my TextChanged Event
My timer doesn't have any code because it is going to perform the bidder00_TextChanged Event.
You could create a method Perform() and call it from within your event handlers :
private void timer1_Tick(object sender, EventArgs e)
{
Perform();
}
private void bidder00_TextChanged(object sender, EventArgs e)
{
Perform();
}
private void Perform()
{
if (bidder00.Text == addbidder1.Text)
{
bidBtn1.PerformClick();
}
}
I assume you have coupled your actual logic with your click event which is not a good idea. Separate the code out into a separate function and have both parts of the application call the same code e.g.
private void SubmitBid()
{
// code you want to execute
}
private void OnSubmitBid()
{
// confirm whether we can actually submit the bid
if (bidder00.Text == addbidder1.Text)
{
SubmitBid();
}
}
private void Timer1_OnTick(object sender, EventArgs e)
{
// trigger code from timer
OnSubmitBid();
}
private void bidder00_TextChanged(object sender, EventArgs e)
{
// trigger code from text change
OnSubmitBid();
}
private void btnBid_Click(object sender, EventArgs e)
{
// trigger code from button press
OnSubmitBid();
}
Notice all the UI controls trigger the same code. There is an extra call in there for the text control validation (i.e. OnSubmitBid()) - if this wasn't required then you would just call SubmitBid directly.

C# object sender - getting the Method from which it was called

I've got these Methods:
private void button_Click(object sender, EventArgs e)
{
//Changes the Text in the RichBox, EXAMPLE:
richtTextBox.Text = "Now Changed and calling Method richTextBox_TextChanged";
}
And,
private void richTextBox_TextChanged(object sender, EventArgs e)
{
//Wants something like that
if(called from button_click)
{
//DO SOMETHING
}
else
{
//DO SOMETHING
}
}
How can I handle this, to know if it was called from the Button_click?
Do I have to use the object sender to get informations? But how?
Hope u guys can help me
Just use a flag:
private bool _isInButtonClick;
private void button_Click(object sender, EventArgs e)
{
try
{
_isInButtonClick = true;
//Changes the Text in the RichBox, EXAMPLE:
richtTextBox.Text = "Now Changed and calling Method richTextBox_TextChanged";
}
finally
{
_isInButtonClick = false;
}
}
private void richTextBox_TextChanged(object sender, EventArgs e)
{
if(_isInButtonClick)
{
//DO SOMETHING
}
else
{
//DO SOMETHING
}
}
private void richTextBox_TextChanged(object sender, EventArgs e)
Here sender is the richTextBox, not the button that changed the text.
You could go into the stack trace to discover if the button click is on the call stack, but that's overkill (like using a nuke to crack a walnut).
Add a flag (bool) to your form, set it to true in the button click, and check it in the TextChanged event, then at the end of the button click, set it to false again.
If you do this I would advise wrapping this signal logic in a class that implements IDispose and use it in using statements.
That said, are you sure you need this functionality?

Categories

Resources