How can I subscribe multiple buttons to the same event handler and act according to what button was clicked?
When you subscribe to the event on a button, it's just a standard event handler:
button1.Click += myEventHandler;
You can use the same code to add handlers for every button:
button1.Click += myEventHandler;
button2.Click += myEventHandler;
button3.Click += myEventHandler;
button4.Click += myEventHandler;
button5.Click += myEventHandler;
button6.Click += myEventHandler;
This will cause your handler in myEventHandler
to be run when any of the buttons are clicked.
How to add one event listener for all buttons
You don't really need to add listeners to all the buttons. There is such thing in JS as Bubbling and capturing so you can wrap all your buttons
with a div
and catch all the events there. But make sure you check that the click was on a button
and not on the div
.
const wrapper = document.getElementById('wrapper');
wrapper.addEventListener('click', (event) => {
const isButton = event.target.nodeName === 'BUTTON';
if (!isButton) {
return;
}
console.dir(event.target.id);
})
div {
padding: 20px;
border: 1px solid black;
}
<div id='wrapper'>
<button id='but1'>
Button1
</button>
<button id='but2'>
Button2
</button>
<button id='but3'>
Button3
</button>
<button id='but4'>
Button4
</button>
</div>
How to check if multiple buttons where clicked in an alphabet soup game
You can try to create buttons and assign event hadlers in a loop:
for (int line = 0; line < 7; ++line) {
for (int column = 0; column < 10; ++column) {
Button button = new Button() {
Parent = this,
Text = "?", // Here you to generate button's text, e.g. with Random
Location = new Point(50 + line * 40, 50 + column * 40),
Size = new Size(30, 30),
};
button.Click += (ss, ee) => {
Button myButton = ss as Button;
myButton.ForeColor = System.Drawing.Color.Red;
};
}
}
If you put all the buttons on the form manually, you can assign event hadlers in a loop as well:
foreach (var button in Controls.OfType<Button>()) {
button.Click += (ss, ee) => {
Button myButton = ss as Button;
myButton.ForeColor = System.Drawing.Color.Red;
};
}
Common event handler for multiple controls of different types in C#
If you add name of the index to the Tag
of control, then you can set bChangedValues
too.
private void Control_ValueChanged(object sender, EventArgs e)
{
var control = (Control)sender;
control.BackColor = CHANGED_COLOUR;
bChangedValues[control.Tag] = true;
}
How can I apply oops in the code below to make it less redundant code?
Did you know you can link multiple buttons to the same event handler? See this answer to learn how.
Once you have all the buttons pointed at the same handler, you can use the same code, except the part that decides whether to add, multiple, divide, or subtract. For that you will need a series of if
statements, checking the sender
to see which button raised the event.
private void MyClickHandler(object sender, EventArgs e)
{
int num1 = 0;
int num2 = 0;
String num = firstNum.Text;
String sNum = secondNum.Text;
if (num == "")
{
MessageBox.Show("error type both num");
}
else
{
num1 = int.Parse(num);
num2 = int.Parse(sNum);
}
int total = 0;
if (sender == addBtn) total = num1 + num2;
if (sender == subBtn) total = num1 - num2;
if (sender == multBtn) total = num1 * num2;
if (sender == divideBtn) total = num1 / num2;
MessageBox.Show(total.ToString());
firstNum.Text = string.Empty;
secondNum.Text = string.Empty;
}
Extra credit
If you really want to be fancy you can get rid of the messy if
statements by using a lookup table with delegates for each operation.
private Dictionary<Control,Func<int,int,int>> _operations = new Dictionary<Control,Func<int,int,int>>
{
{ addBtn, (x,y) => x + y },
{ subBtn, (x,y) => x - y },
{ multBtn, (x,y) => x * y },
{ divideBtn, (x,y) => x / y }
};
private void MyClickHandler(object sender, EventArgs e)
{
int num1 = 0;
int num2 = 0;
String num = firstNum.Text;
String sNum = secondNum.Text;
if (num == "")
{
MessageBox.Show("error type both num");
}
else
{
num1 = int.Parse(num);
num2 = int.Parse(sNum);
}
int total = _operations[sender](num1,num2);
MessageBox.Show(total.ToString());
firstNum.Text = string.Empty;
secondNum.Text = string.Empty;
}
Related Topics
How to Get the Assembly File Version
Xml Serialize Generic List of Serializable Objects
How to Deserialize a Complex JSON Object in C# .Net
How to Get a Human-Readable File Size in Bytes Abbreviation Using .Net
Display Image from Database in Asp MVC
How to Get More Than 1000 Records from a Directorysearcher
Linq Ring: Any() VS Contains() for Huge Collections
The Type of One of the Expressions in the Join Clause Is Incorrect in Entity Framework
Format an Excel Column (Or Cell) as Text in C#
Why Should I Use Ihttpactionresult Instead of Httpresponsemessage
How to Quickly Check If Two Data Transfer Objects Have Equal Properties in C#
.Net: Determine the Type of "This" Class in Its Static Method
How to Mock Non Virtual Methods
Install a .Net Windows Service Without Installutil.Exe