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.
Related
This question already has answers here:
WinForms: How to programmatically fire an event handler?
(4 answers)
Closed 2 years ago.
I am using C# in WinForms to use a trackbar as follows. At the beginning of the code I define the event handler:
this.trackBar1.Scroll += new System.EventHandler(this.trackBar1_Scroll);
And here is the implementation when one scrolls the trackbar:
private void trackBar1_Scroll(object sender, EventArgs e)
{
//do something...
}
So this works, but I need to call the above function from inside another event handler such as:
public void numericUpDown1_TextChanged(object sender, EventArgs e)
{
//what to do here to call trackBar1_Scroll ?
}
What could be done to call trackBar1_Scroll from inside numericUpDown1_TextChanged?
Very often you do not need the sender and e parameters. Therefore just create a parameterless method
private void DoSomething() // Hopefully with a better name
{
// do things ...
}
and then call it inside your event handlers.
private void trackBar1_Scroll(object sender, EventArgs e)
{
DoSomething();
}
public void numericUpDown1_TextChanged(object sender, EventArgs e)
{
DoSomething();
}
If you give the method a descriptive name, your code becomes easier to read. But of course you could as well just call the other event handler. The event handler is just a method after all
public void numericUpDown1_TextChanged(object sender, EventArgs e)
{
trackBar1_ValueChanged(sender, e);
}
Since both of these event handlers have the same signature (the same parameter list and return type), you could declare a single one and attach the same to both controls:
void HandleUpdates(object sender, EventArgs e)
{
// do things...
}
And assign it with
trackBar1.Scroll += HandleUpdates;
numericUpDown1.TextChanged += HandleUpdates;
You can also assign it in the properties window on the events tab. new System.EventHandler(...) is not necessary. C# does it automatically for you.
I have two static labels that are supposed to show the users counters that I have kept on the back end but they do not change on the form. I have tried searching for answers but I can't understand most of them.
//Watchers
private static void CDdirWatcher_Created(object sender, FileSystemEventArgs e)
{
CDCreated += 1;
}
private static void LPdirWatcher_Created(object sender, FileSystemEventArgs e)
{
LPCreated += 1;
}
So the above are events where my counters go up
And below is the events I'm trying to make to create the change to the labels.
private void cdCounterLbl_TextChanged(object sender, EventArgs e)
{
cdCounterLBL.Text = CDCreated.ToString();
}
private void lpCounterLbl_TextChanged(object sender, EventArgs e)
{
lpCounterLBL.Text = Convert.ToString(LPCreated);
}
I'm trying
cdCounterLBL.TextChanged += cdCounterLbl_TextChanged;
lpCounterLBL.TextChanged += lpCounterLbl_TextChanged;
I've tried the above but the labels still don't change
Thank you for taking the time to share your problem.
It seems that you misunderstood what are things like classes, variables, methods and events, and how to use them.
That said and if I understood what you want to do, this may solve your problem.
TextChanged, for label, is raised when you change the Text property by code.
It is not because you change the values of your counters that some event will be raised for the labels.
Counters and labels are two separate things, totally different and unrelated, without links, but you can link as follows:
private static void CDdirWatcher_Created(object sender, FileSystemEventArgs e)
{
CDCreated += 1;
cdCounterLbl_TextChanged(this, null);
}
private static void LPdirWatcher_Created(object sender, FileSystemEventArgs e)
{
LPCreated += 1;
lpCounterLbl_TextChanged(this, null);
}
private void cdCounterLbl_TextChanged(object sender, EventArgs e)
{
cdCounterLBL.Text = CDCreated.ToString();
}
private void lpCounterLbl_TextChanged(object sender, EventArgs e)
{
lpCounterLBL.Text = LPCreated.ToString();
}
So that does not work because of static methods and we have a bad design because of calling TextChanged to change the Text.
Thus here how to do.
Add a static event:
private static Action CountersUpdated;
Add in the form's Load event:
CountersUpdated += DoUpdateCounters;
And in the form's FormClosed event:
CountersUpdated -= DoUpdateCounters;
With:
private void DoUpdateCounters()
{
cdCounterLBL.Text = CDCreated.ToString();
lpCounterLBL.Text = LPCreated.ToString();
}
Now you can write:
private static void CDdirWatcher_Created(object sender, FileSystemEventArgs e)
{
CDCreated++;
CallCountersUpdated();
}
private static void LPdirWatcher_Created(object sender, FileSystemEventArgs e)
{
LPCreated++;
CallCountersUpdated();
}
private static void CallCountersUpdated()
{
if ( CountersUpdated != null ) CountersUpdated();
}
You can also make two events for CDCounterUpdated and LPCounterUpdated instead of one CountersUpdated.
Have a good job and a good life in C# and OOP.
I have four events:
View.AdditionPerformed += new EventHandler<EventArgs>(OnOperationPerformed);
View.SubtractionPerformed+=new EventHandler<EventArgs>(OnOperationPerformed);
View.DivisionPerformed+=new EventHandler<EventArgs>(OnOperationPerformed);
View.MultiplyPerformed+=new EventHandler<EventArgs>(OnOperationPerformed);
and one method:
private void OnOperationPerformed(object sender, EventArgs e)
{
}
How can I define which event raised my method? Something like this:
private void OnOperationPerformed(object sender, EventArgs e)
{
switch(event)
{
case MultiplyPerformed:{}
case DivisionPerformed:{}
...
}
}
Write your own EventArgs which has an enum inside, telling you the raised event.
enum MyEventEnum
{
AdditionPerformed,
SubtractionPerformed,
DivisionPerformed,
MultiplayPerformed
}
The EventArgs
class MyEventArgs : EventArgs
{
public MyEventEnum EventRaised { get; set; }
}
Define the Handlers
View.AdditionPerformed += new EventHandler<MyEventArgs>(OnOperationPerformed);
View.SubtractionPerformed+=new EventHandler<MyEventArgs>(OnOperationPerformed);
View.DivisionPerformed+=new EventHandler<MyEventArgs>(OnOperationPerformed);
View.MultiplyPerformed+=new EventHandler<MyEventArgs>(OnOperationPerformed);
When you call them:
this.AdditionPerformed(this, new MyEventArgs
{ EventRaised = MyEventEnum.AdditionPerformed };
I know it's pretty hardcoded, but there isn't any other way.
Instead of using EventArgs, you could use your own event argument class to pass in the necessary data to make the choice inside the handler.
It would then become available on your e variable inside the handler.
Cheers
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 am having a problem in calling multiple buttons at the same time because each buttons works a different process there are more than 78 folders.
I want to call all the buttons at the same time in a single button called button4. Now it's calling button1 only and not working for button2.
Is there any way to call these buttons at the same time?
My code is:
private void button4_Click_1(object sender, EventArgs e)
{
button1.PerformClick();
button2.PerformClick();
}
Thanks in Advance.
You should in general not perform UI-style clicks on other buttons in order to invoke their behaviour.
Just call the respective event handling methods of the buttons you would like to "click".
example code:
private void button4_Click_1(object sender, EventArgs e)
{
button1_Click_1(null, EventArgs.Empty);
button2_Click_1(null, EventArgs.Empty);
// and so on
}
You should refactor the other events to call well-named methods.
Say button1 does some initialization; it should look like this:
private void button1_Click(object sender, EventArgs e)
{
Initialize();
}
Say button2 finalizes that intialization; it should look like this:
private void button2_Click(object sender, EventArgs e)
{
FinalizeInitialization();
}
Then if button4 does all of this; it should look like this:
private void button4_Click(object sender, EventArgs e)
{
Initialize();
FinalizeInitialization();
WhateverElseButton4ShouldDo();
}
Under most circumstances, you shouldn't call PerformClick() at all. Instead, you should call the same methods your event handlers call. So, if clicking button 3 should behave as click clicking button 1 and then button 2, you should have code like this:
private void button1_Click(object sender, EventArgs e)
{
SomeAction();
}
private void button2_Click(object sender, EventArgs e)
{
AnotherAction();
}
private void button3_Click(object sender, EventArgs e)
{
SomeAction();
AnotherAction();
}
(As a side note, your buttons should have descriptive names, not button1 and the like.)
We can't say what those button click handlers do. So it's hard to say what's wrong. But try moving the code away from button click handlers. Create some class that contains code that should run after button click. Then call this class' methods from button click handlers. It will be easier to debug and test that code.
public class ButtonActions
{
public void DoSomething() {...}
public void DoSomething2() {...}
public void DoSomething3() {...}
public void DoAll()
{
DoSomething();
DoSomething2();
DoSomething3();
}
}
// here instead of clicking all buttons call method that does it all
protected void button_Click(object sender, EventArgs e)
{
var buttonActions = new ButtonActions();
buttonActions.DoAll();
}