Set up single event handler for multiple buttons - c#

Hi im practically new to C# i usually program with c++ so please bear with me. I am coding an application and i have 10 buttons, 5 of which which are practically doing the same thing. Currently I have 5 event handlers doing the same thing. How can I change this to a single even handler with if statements. Also my problem is that even though the methods of each button are the same i have some small differences from one to another as described below:
button 1 copared with button 5
button 2 copmpared with button 6
button 3 compared with button 7 and so on
How can i tackle this small difference in each case?
Thankyou so much

button.SomeEvent += SomeHandler
void SomeHandler(object sender, EventArgs e)
{
Button b = (Button)sender; //get the specific button that was pressed
...
}
Use the += operator to add a method to an event and simply add the same method.

You could set them all to the same handler, get the button that called it, check the id in an if statement and do different actions -- OR -- you could use the much more common refactor that looks like this:
void Button1Action(object sender, EventArgs e)
{
// do stuff for button 1 here
SharedCode();
}
void Button2Action(object sender, EventArgs e)
{
// do stuff for button 2 here
SharedCode();
}
void Button3Action(object sender, EventArgs e)
{
// do stuff for button 3 here
SharedCode();
}
void Button4Action(object sender, EventArgs e)
{
// do stuff for button 4 here
SharedCode();
}
void SharedCode()
{
// do stuff for all buttons
}

Related

Need to know which of two buttons was pressed before for a third button event handler

Hey guys first month student here , I need to handle a button event based on which button was clicked before , any simple ideas ? ..(example I've got a listbox with a list of actors and depending on if I click "new actor(first button)" or "modify actor(second button)" I need to either add a new actor or modify the existing actor's stats with the "add button (third button --> needs to know which button was clicked before)".. ??
You can declare a variable of type Button to save the button clicked before.
Note: use Null-conditional operator ?. to avoid potential exception System.NullReferenceException.
Button btn;
private void btnAdd_Click(object sender, EventArgs e)
{
Console.WriteLine(btn?.Name); // print button name
}
private void btnNew_Click(object sender, EventArgs e)
{
btn = btnNew;
}
private void btnModify_Click(object sender, EventArgs e)
{
btn = btnModify;
}

C# - Proper way to run sequential tasks?

New to C# and learning as i go. I've tried Googling, but havent found what im looking for (still looking).
I have a simple C# App that so far is working fine. The next part i want to figure out is how to invoke a series of tasks/methods.
Say i have 4 individual tasks (Tasks 1-4). Each one of them does something different...
Button 1 - Shows a Messagebox
Button 2 - Changes a label text color
Button 3 - Writes something to console.
etc
etc.
Each one of these works fine when you press its associated button. But now lets say i have a Checkbox next to each of these that you can check/uncheck. Plus a button that says "run selected".
My question is how do i program that button to run ALL the tasks in sequential order AND only run the tasks that are selected?
Checkbox 1 - OFF
Checkbox 2 - ON
Checkbox 3 - OFF
Checkbox 4 - ON
So when i press the "Run Selected" Button - Only Tasks 2 and 4 run.
Again, im new, and my lingo may not be correct - but hopefully you get the idea.
Thanks,
Mike
First of all, I would isolate each task outside the click handlers of the buttons, into its own methods:
private void Task1()
{
MessageBox.Show("Task 1");
}
private void Task2()
{
MessageBox.Show("Task 2");
}
private void Task3()
{
MessageBox.Show("Task 3");
}
private void Task4()
{
MessageBox.Show("Task 4");
}
I just used simple message boxes for the sake of simplicity, but any code will work actually.
Then make each click handler just call each method:
private void button1_Click(object sender, EventArgs e)
{
this.Task1();
}
private void button2_Click(object sender, EventArgs e)
{
this.Task2();
}
private void button3_Click(object sender, EventArgs e)
{
this.Task3();
}
private void button4_Click(object sender, EventArgs e)
{
this.Task4();
}
Now the important part, when the "do all checked" button is clicked, you check each checkbox state and launch the appropriate method in sequence:
private void button5_Click(object sender, EventArgs e)
{
if (this.checkBox1.Checked) this.Task1();
if (this.checkBox2.Checked) this.Task2();
if (this.checkBox3.Checked) this.Task3();
if (this.checkBox4.Checked) this.Task4();
}

C# Form - MouseClick will click the actual control after losing form focus

If you ever remove focus from any professional application like Chrome/FireFox/Visual Studio, and then reclick a button/menu item, it will actually click it as if you never lost focus.
How can I apply the same concept in C# WinForm? I tried many things like
private void form1_MouseClick(object sender, MouseEventArgs e)
{
BringToFront();
Activate();
}
Activate/focus/select/etc... nothing worked to react the same way, it always takes 3-4 clicks to actually click on a menu!
I thought about making a click event for every single control, but that seemed rather redundant.
Check this for example (Yellow Clicks)
You are right about Menues taking an extra click to get focus.
Which is extra annoying since the menue get highlighted anyway but doesn't react to the 1st click..
You can avoid that by coding the MouseEnter event:
private void menuStrip1_MouseEnter(object sender, EventArgs e)
{
// either
menuStrip1.Focus();
// or
this.Focus();
}
The downside of this is, that it is stealing focus from other applications, which is not something a well-behaved application should do..
So I think it is better to wait for a definitive user action; code the MouseDown event in a similar way..:
private void menuStrip1_MouseDown(object sender, MouseEventArgs e)
{
menuStrip1.Focus();
}
Or use the event that was made for the occasion:
private void menuStrip1_MenuActivate(object sender, EventArgs e)
{
menuStrip1.Focus();
}
I can't confirm a similar problem with Buttons or any other controls, though.
I have find trick to solve your problem. it work for me 100%
See this code:
dynamic elem1;
private void menuStrip1_MouseEnter(object sender, EventArgs e)
{
elem1 = sender;
}
private void menuStrip1_MouseLeave(object sender, EventArgs e)
{
elem1 = null;
}
private void Form1_Activated(object sender, EventArgs e)
{
if(elem1 != null){
elem1.PerformClick();
if (elem1.GetType().ToString() == "System.Windows.Forms.ToolStripMenuItem") elem1.ShowDropDown();
}
elem1 = null;
}
Here what happend.
When mouse enter button/menu item elem1 = this button/menu, and when mouse leave it set back to null.
so when form Activated we can call elem1.PerformClick() to click the button/menu item.

Why it is not Possible to call textBox1_KeyPress() event from some Button Click event.?

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn0_Click(object sender, EventArgs e)
{
MessageBox.Show("called btn 0 click..");
KeyPressEventArgs e0 = new KeyPressEventArgs('0');
textBox1_KeyPress(sender, e0);
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
MessageBox.Show("called txtbox_keypress event...");
}
}
Am sorry if this is a silly question,I have just started to learn windows forms, I still find material on the internet confusing.I want to implement calculator. So when number button is pressed it should be filled in textbox. So I thought calling textBox1_keypress() event from button click event would work??? but its not working,
I can manually write the logic in button click event to fill text in text box but if i do so, i have to do the same thing in button1_KeyPress event too. so it would be duplication of code right??...so i thought solution was to call textBox1_KeyPress() event from both button click event and button key press event...but its not working .So what should i do???..is there any other approach which should i follow.
so it would be duplication of code right??
Yes, it would be. So you can do
private void btn0_Click(object sender, EventArgs e)
{
CommonMethod(e);
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
CommonMethod(e);
}
private void CommonMethod(EventArgs e)
{
//Your logic here.
}
The TextBox KeyPress event handler (textBox1_KeyPress) is called after the user presses a key. The KeyPressEventArgs parameter includes information such as what key was pressed. So calling it from your btn0_Click method isn't going to set the text for the TextBox.
Rather, you want to (probably) append whatever number the user pressed to the text already present in the TextBox. Something like
private void btn0_Click(object sender, EventArgs e)
{
textBox1.Text += "0";
}
might be closer to what you're trying to accomplish.
You could put the logic in an extra function like so:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn0_Click(object sender, EventArgs e)
{
NumberLogic(0),
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
// I don't know right now if e contains the key pressed. If not replace by the correct argument
NumberLogic(Convert.ToInt32(e));
}
void NumberLogic(int numberPressed){
MessageBox.Show("Button " + numberPressed.ToString() + " pressed.");
}
}
You don't want to tie the events together like that.
A key-press is one thing, handled in one way.
A button click is something totally different and should be handled as such.
The basic reason is this,
The button doesn't know what number it is, you need to tell it that.
A key-press on the other hand, knows what number was pressed.
If you REALLY want to, for some reason, you could use SendKeys to trigger your key-press event in a round-about way, from the button.
SendKeys.SendWait("0");
I can suggest to you to use an Tag Property of the Buttons. Put in it the value of each button in Design mode or in Constructor, create one button event handler for all buttons and use Tag value:
Constructor:
button1.Tag = 1;
button2.Tag = 2;
button1.Click += buttons_Click;
button2.Click += buttons_Click;
Event hadler:
private void buttons_Click(object sender, EventArgs e)
{
textBox1.Text = ((Button)sender).Tag.ToString();
}

handling multiple button actions in one action in C#

I have 70 buttons whose names are like button1, button2, button3 and so on.
My aim is that whenever button1 is clicked, it will say "1", button2 will say as "2" and so on for the others.
The code for button1 to speak is:
SpeechSynthesizer synthesizer = new SpeechSynthesizer();
private void button1_Click(object sender, EventArgs e)
{
synthesizer.Speak("1");
}
For button2
private void button2_Click(object sender, EventArgs e)
{
synthesizer.Speak("2");
}
and so on for other 68 buttons.
Now it is difficult to implement the 70 button's actions. These button actions follow a pattern - so can anyone suggest a more efficient way I can implement these button handlers to save me writing out 70 different actions?
Try something like this
button1.Tag = "1";
button2.Tag = "2";
...
private void button_Click(object sender, EventArgs e)
{
synthesizer.Speak(((Button)sender).Tag.ToString());
}
Use same handler for all buttons. Sender of event will be the button which raised event. You can get it's name and extract text to say:
private void button_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
string text = button.Name.Substring("button".Length);
synthesizer.Speak(text);
}
Create a single handler for all of the buttons.
Cast the sender parameter to get the Button instance that was clicked, and figure out what to do based on its Name, Text, or Tag.
Depending on your UI, you might want to generate all of those buttons in a loop, too.
You can subscribe them to a single eventhandler.
thus:
button1.Click += buttonClicked;
button2.Click += buttonClicked;
// and so on
and the code for the buttonClicked;
private void buttonClicked(object sender, EventArgs e)
{
//This will get the Type first, the name and then the last character on the Name
synthesizer.Speak(sender.GetType().Name.Substring(sender.GetType().Name.Length - 1, 1));
}
this promotes code reuse for you :)

Categories