I'm making an XNA game and I have a question about the convention for events.
I made a menu which has buttons, those buttons have 3 events naimly: onClick, onMouseEnter and onMouseLeave.
Atm my code looks like this :
public static void PlayonClick(Button sender, EventArgs args)
{
}
public static void PlayonMouseEnter(Button sender, EventArgs args)
{
}
public static void PlayonMouseLeave(Button sender, EventArgs args)
{
}
This code will repeat for every button in the menu.
Now I think it would be better if had 1 event and eventargs will contain what happend (onClick,onMouseLeave,onMouseEnter)
Note: onMouseEnter and onMouseLeave are acttualy the same for every button. So I'm thinking to subscribe all events to 1 method
So, What is they best way to implement this ?
Assuming you're attaching your handlers in code:
button.onClick += PlayonEvent;
button.onMouseEnter += PlayonEvent;
button.onMouseLeave += PlayonEvent;
If attaching in XAML, do the same sort of thing, which is simply to say that all of the events are handled by the same handler. Either way, define such a handler like:
public static void PlayonEvent(Button sender, EventArgs args)
{
// do something based on EventArgs, which can give you an idea of what's going on
}
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 a form with 6 buttons. These buttons serve to increase/decrease tha value of the respective textbox. Now I'm trying to "animate" the buttons. I want to get another effect on the button when the mouse is over him.
To do that, I have two diferent images in Resources and I am doing this code:
private void btnHoursDown_MouseHover(object sender, EventArgs e) {
btnHoursDown.Image = Game_Helper.Properties.Resources.DownHover;
}
private void btnHoursDown_MouseLeave(object sender, EventArgs e) {
btnHoursDown.Image = Game_Helper.Properties.Resources.Down;
}
This works fine. My question is: it wouldn't be wise to create a class (ButtonBehaviour.cs) and put this code in that class?
So I would have something like this:
ButtonBehaviour buttonBehaviour = new ButtonBehaviour();
private void btnHoursDown_MouseHover(object sender, EventArgs e) {
buttonBehaviour.buttonDownHover();
}
private void btnHoursDown_MouseLeave(object sender, EventArgs e) {
buttonBehaviour.buttonDownLeave();
}
And the class should be:
public class ButtonBehaviour {
public void buttonDownHover() {
// code
}
public void buttonDownLeave() {
// code
}
}
How can I create this Class Behaviour and make the buttons adapt this Behaviour?
if one effect should be applied for all buttons, try to add the same event handlers to them
private void btn_MouseHover(object sender, EventArgs e)
{
(sender as Button).Image = Game_Helper.Properties.Resources.DownHover;
}
private void btn_MouseLeave(object sender, EventArgs e)
{
(sender as Button).Image = Game_Helper.Properties.Resources.Down;
}
button which raised event is available via sender variable
this way you avoid code duplication for every button. creating a ButtonBehaviour or CustomButton is probably an over-engineering unless you need them in many forms
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.
Im making a userControl named [File_Manager] and i was wondering if i can add a button to this custom control that i can set its job later after adding this custom control to another form .. something like
File_Manager fManager = new File_Manager();
fManager.SetFreeButtonJob( MessageBox.Show("Hello") ); // something like this.
then whenever user press that button .. the messageBox shows up.
So.. Is it possible to do that?
thanks in advance.
Sure you can. Just attach the buttons click handler to the action you pass in.
fManager.SetFreeButtonJob(() => MessageBox.Show("Hello"));
private void SetFreeButtonJob(Action action)
{
button1.Click += (s,e) => action();
}
Just note that passing in the Action breaks the encapsulation of user control though. You should probably do something like SetFreeButtonJob(Jobs.SayHello); and put the knowledge of what to do inside the control.
Create a custom event for your UserControl and fire it when your Button is clicked. You can then attach an event handler to the custom event in your Form. Or you can just raise the UserControl's Click Event when your Button is clicked.
public delegate void CustomClickEventHandler(object sender, EventArgs e);
public partial class buttonTest : UserControl
{
public event CustomClickEventHandler CustomClick;
public buttonTest()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
CustomClick(sender, e);
}
}
and in your Form
public Form1()
{
InitializeComponent();
buttonTest1.CustomClick +=new CustomClickEventHandler(userControl1_ButtonClick);
}
private void userControl1_ButtonClick(object sender, EventArgs e)
{
MessageBox.Show("Hello");
}
Or as my second option try.
private void button2_Click(object sender, EventArgs e)
{
OnClick(e);
}
and in your Form subscribe to the UserControl's Click event.
buttonTest1.Click +=new EventHandler(buttonTest1_Click);
private void buttonTest1_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello Again");
}
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();
}