why do events exist? - c#

Yes, alright, it is probably a stupid question but I can´t understand events. I mean that I understand what delegates are for, I can create avents and handle them but I don´t actually understand them. Let´s say I have the following code with event in the Form1.cs file:
private void btnSleep_Click(object sender, EventArgs e)
{
_currentPerson.Sleep();
}
private void lvPeople_SelectedIndexChanged(object sender, EventArgs e)
{
if (lvPeople.SelectedItems.Count > 0)
{
_currentPerson = (Person)lvPeople.SelectedItems[0].Tag;
_currentPerson.FellAsleep += _currentPerson_FellAsleep;
}
}
void _currentPerson_FellAsleep(object sender, EventArgs e)
{
lvPeople.SelectedItems[0].BackColor = Color.Aqua;
}
In the Person class I have this:
public delegate void PersonEventsHandlers(Object sender, EventArgs e);
public event PersonEventsHandlers FellAsleep;
public void Sleep()
{
this._isSleeping = true;
FellAsleep(this, EventArgs.Empty);
}
So everything works fine, cool. But if I do this change and forget the Person events works anyways.
private void btnSleep_Click(object sender, EventArgs e)
{
_currentPerson.Sleep();
lvPeople.SelectedItems[0].BackColor = Color.Aqua;
}
So why should I use the Person events?!
Thank you.

Events are all about deferred execution... I want to define the behaviour of something but not execute it right now... later under certain conditions. It is a way to register lazy functionality that is executed when needed.
This is especially useful when distributing a compiled assembly. People can add to the functionality of your assembly without recompilation.

Related

How to implement button_click event without clicking button [duplicate]

This question already has answers here:
Triggering a button click through code
(6 answers)
Closed 4 years ago.
private void btnSend_Click(object sender, EventArgs e)
{
Dosomething();
}
private void Something(object sender, EventArgs e)
{
btnSend_click( how to write in here?? )
}
I want to implement btnSend_Click in other section(?), but i don't know how to do this. i want to implement this code without using UI.
If you just need to call the method btnSend_Click from the method Something, you can pick any of these:
private void Something(object sender, EventArgs e)
{
btnSend_click(this, EventArgs.Empty);
}
Or
private void Something(object sender, EventArgs e)
{
btnSend_click(sender, e);
}
It is all about naming, that is, giving the methods a good name.
First, you write the underlying method that does the actual work.
public class Someone
{
public void DoSomething()
{
Console.Beep(); //make a noise
}
}
At this point, no UI is involved, no button, no sender, no EventArgs.
Then
Call this method when the button is clicked.
private void btnSend_Click(object sender, EventArgs e)
{
new Someone().DoSomething();
}
Call this method from any other place.
class AnotherOne
{
private void DoAnotherThing()
{
new Someone().DoSomething();
}
}
I don't answer your question on how to call btnSend_click from anywhere by passing faked sender and EventArgs.
Because that is not a good idea to write such calls - before long you will be confused by the names even if the code was written by yourself.

More efficient way to format several nearly identical functions?

I was wondering if there was a more efficient way to format the following code:
private void nmudc1_Enter(object sender, EventArgs e)
{
SelectAllNumericalUpDownText(nmudc1);
}
private void nmudc1_Click(object sender, EventArgs e)
{
SelectAllNumericalUpDownText(nmudc1);
}
private void nmudc2_Enter(object sender, EventArgs e)
{
SelectAllNumericalUpDownText(nmudc2);
}
private void nmudc2_Click(object sender, EventArgs e)
{
SelectAllNumericalUpDownText(nmudc2);
}
And so on.
I apologize if this has been asked before or elsewhere, and I assume the answer is relatively simple. Unfortunately, I have been unsuccessful in finding a suitable answer thus far.
I have thought about trying to put in in an array, or an object, but I really just have no idea how I would go about doing this to a function like this.
Thank you.
You can create only one event function, And send the sender as parameter to the SelectAllNumericalUpDownText function.
Register all events to this function:
nmudc1.Click += nmudc_Event;
nmudc1.Enter += nmudc_Event;
nmudc2.Click += nmudc_Event;
nmudc2.Enter += nmudc_Event;
Generic implementation to the function:
private void nmudc_Event(object sender, EventArgs e)
{
SelectAllNumericalUpDownText(sender as <TYPE>);
}
Since all event handlers in your code sample have the same method signature, you can simply use the same method to handle all the events:
private void NumericUpDown_event(object sender, EventArgs e)
{
SelectAllNumericalUpDownText(sender as NumericUpDown);
}
This is assuming, of course, that your sender object is actually a NumericUpDown.
You could use the following alternative:
private void NumericUpDown_Event(object sender, EventArgs e)
{
if (!(sender is <controltype> nump))
return;
SelectAllNumericalUpDownText(nump);
}
By this you do not call the method if the sender is not of type < controltype >. Therefor you already used the generic EventArgs class you can subscript the Enter/Click event to this method.

Find which Event was Fired

I am attempting to capture which Event was fired. I have two events that point to the same function, CurrentLoan_LogEntryEvent. Inside CurrentLoan_LogEntryEvent, how do I determine which Event was actually fired: LogEntryAdded or LogEntryChange.
Below you'll find sample of my code how I have it now. Let me know if you have any questions about my code.
CurrentLoan is a Loan object, which has two events.
public MyApplication()
{
ThirdPartyDLL.LoanOpened += new EventHandler(CurrentLoanOpened);
}
private void CurrentLoanOpened(object sender, EventArgs e)
{
ThirdPartyDLL.CurrentLoan.LogEntryAdded += CurrentLoan_LogEntryEvent;
ThirdPartyDLL.CurrentLoan.LogEntryChange += CurrentLoan_LogEntryEvent;
}
private void CurrentLoan_LogEntryEvent(object sender, LogEntryEventArgs e)
{
// When LogEntry was Added or Changed.
// How do I determine if LogEntryAdded or LogEntryChange was fired?
}
If you want to differentiate two events, no point in attaching a single method for multiple events. Give them different handlers.
You typically attach single handler for multiple events when you don't care about where the event origin, but you always wanted to do the same thing in the handler.
If you have some common logic to be executed, you can call it inside the handlers.
private void CurrentLoanOpened(object sender, EventArgs e)
{
ThirdPartyDLL.CurrentLoan.LogEntryAdded += CurrentLoan_LogEntryAdded;
ThirdPartyDLL.CurrentLoan.LogEntryChange += CurrentLoan_LogEntryChange;
}
private void CurrentLoan_LogEntryAdded(object sender, LogEntryEventArgs e)
{
//LogEntryAdded fired
YourOptionalCommonMethodIfAny();
}
private void CurrentLoan_LogEntryChange(object sender, LogEntryEventArgs e)
{
//LogEntryChange fired
YourOptionalCommonMethodIfAny();
}
Why don't you simply do this:
private void CurrentLoanOpened(object sender, EventArgs e)
{
ThirdPartyDLL.CurrentLoan.LogEntryAdded += CurrentLoan_LogEntryAddedEvent;
ThirdPartyDLL.CurrentLoan.LogEntryChange += CurrentLoan_LogEntryChangeEvent;
}
private void CurrentLoan_LogEntryAddedEvent(object sender, LogEntryEventArgs e)
{
// First do what you must do specifically for added events
CurrentLoan_LogEntry(e);
}
private void CurrentLoan_LogEntryChangeEvent(object sender, LogEntryEventArgs e)
{
// First do what you must do specifically for changed events
CurrentLoan_LogEntry(e);
}
Binding one handler to multiple events and then figuring out what to do inside that handler is just overcomplicating things.
Always keep your code as simple to understand and change as possible.

How to trigger an event handler from within another event, C#

So I have a form where I want to change the position of a trackbar and trigger the trackbar_scroll event after I click on a label. So far, clicking on the label changed the value of the trackbar, thats easy:
private void label4_Click(object sender, EventArgs e)
{
trackBar1.Value = 0;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
if (trackBar1.Value == 0)
{
try
{
//code...
}
catch
{
MessageBox.Show("Error occured");
}
}
}
How do I call the trackBar1_scroll(..) event from within the label click?
Try calling it directly. You just have to supply the parameters yourself:
trackBar1_Scroll(trackBar1, EventArgs.Empty);
or simply
trackBar1_Scroll(null, null);
if the parameters are not being utilized.
Another approach you could take, aside from #LarsTech answer (which is absolutely correct), would be to refactor your code to reduce the need to supply empty parameters. Since you're not actually using the EventArgs or referencing the sender directly, given your example above, you could do something like the following:
private void DoSomething(int value)
{
...
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
DoSomething(trackBar1.Value);
}
private void label4_Click(object sender, EventArgs e)
{
DoSomething(...);
}
It always feels like code smell to me, when you call an event handler with empty parameters, simply to execute code which you could otherwise abstract out.

I want to call a visual c# event within another event. How do I do that?

I want to call btnDisconnect_Click within btnExit_Click.
private void btnDisconnect_Click(object sender, EventArgs e)
{
//does something
}
private void btnExit_Click(object sender, EventArgs e)
{
//I want to call btnDisconnect_Click. What line of code should I use here?
}
Usually in cases like these I make my click handlers only call another function and pass in appropriate arguments:
private void btnDisconnect_Click(object sender, EventArgs e)
{
DoDisconnect();
}
private void DoDisconnect()
{
...
}
Then I can call that same function from wherever:
private void btnExit_Click(object sender, EventArgs e)
{
DoDisconnect();
}
This way your "disconnect" logic is gummed up by taking dummy arguments that don't actually affect the disconnect behavior in any way.
It also means you can start factoring out view logic from forms.
That depends on if you are using the arguments passed to the event handlers
You could yust call it using nulls
Something like
private void btnDisconnect_Click(object sender, EventArgs e)
{
//does something
}
private void btnExit_Click(object sender, EventArgs e)
{
//I want to call btnDisconnect_Click. What line of code should I use here?
btnDisconnect_Click(null,null);
}
They're just methods. Just call it. You'll need to provide whatever event arguments btnDisconnect_Click is expecting (which is probably nothing). So the simplest thing is:
private void btnExit_Click(object sender, EventArgs e)
{
btnDisconnect_Click(this, EventArgs.Empty);
}
This will pass the current form/window/whatever it is as the sender, and an EventArgs object with no data.
You can call it just as you have it listed. The this below isn't necessary but it puts context on the code:
private void btnExit_Click(object sender, EventArgs e)
{
//I want to call btnDisconnect_Click. What line of code should I use here?
this.btnDisconnect_Click(null, null);
// If you need to have sender as something you can always put
// this in directly
this.btnDisconnect_Click(this.btnDisconnect, new System.EventArgs());
}
I'm going to make an assumption here and say that what you're trying to do is call a Disconnect (perhaps a network resource) for both the disconnect and exit buttons. Instead of calling one event handler method from the other you may want to refactor the disconnect event handler's code into a separate method. Then call that method from both handlers. For example:
private void Disconnect()
{
//Disconnect here
}
private void btnDisconnect_Click(object sender, EventArgs e)
{
//do some other stuff here
Disconnect();
}
private void btnExit_Click(object sender, EventArgs e)
{
//do some other exit stuff here
Disconnect();
}
This makes your code much cleaner and saves you from having to call one event handler from another. This begins to separate your view logic from the rest of your program's logic, which is much more desirable and much easier to maintain in the long run. For instance you may want a separate controller for handling the network resource, instead of embedding it into the view's logic.
In the simplest case you can just call the btnDiconnect_Click directly as follows:
private void btnDisconnct_Click(Object sender, EventArgs e)
{
//Does Something
}
private void btnExit_Click(Object sender, EventArgs e)
{
//Call btnDisconnect_Click()
btnDisconnect_Click(sender, e);
}
You could just call the method passing in valid parameters.
btnDisconnect_Click(btnDisconnect,new EventArgs());
However you might want to consider refactoring out the code in btnDisconnect into a new method and calling that instead:
private void doSomething()
{
//....
}
private void btnDisconnect_Click(object sender, EventArgs e)
{
doSomething();
}
private void btnExit_Click(object sender, EventArgs e)
{
doSomething();
}
{// this is probably your constructor
.
public delegate void MyCustomHandler(object sender, EventArgs e);
.
MyCustomHandler myCustomHandler = new MyCustomHandler(); //you can do more in your delegates constructor, members etc
myCustomHandler += btnExit_Click;
myCustomHandler += btnDisconnect_Click;
}
private void btnDisconnect_Click(object sender, EventArgs e)
{
// do Something
}
private void btnExit_Click(object sender, EventArgs e)
{
// do Something
}
//And wherever you need to invoke these, you do
myCustomHandler(object sender, EventArgs e);

Categories