Reputation: 778
I'm programming a calculator with C# Windows Forms. I want to listen to the number keys and perform a Button.PerformClick()
on the Button which has the same number in its variable name. My buttons are named after the pattern: btn1, btn2, btn3, etc.
My code:
switch (c) //c is the KeyChar Value of the pressed Key
{
case '1':
{
btn1.PerformClick();
break;
}
case '2':
{
btn2.PerformClick();
break;
}
case '3':
{
btn3.PerformClick();
break;
}
...
case '9':
{
btn3.PerformClick();
break;
}
}
Is there something better code-wise, than just copying everything again and again 9 times? I've tried following (didn't work):
foreach(Button btn in this.Controls){
if(btn.Text == c.ToString) //c is the KeyChar value
{
btn.PerformClick();
}
}
Am I doing something wrong or are there any better/smoother ways of doing this, or do I have to do it the way I did?
Upvotes: 2
Views: 576
Reputation: 35400
I'd simply set the Tag
of each of the 10 buttons to its numeric value and use a single Click event handler for all 10 buttons. Then in the handler routine I'd just read the Tag
of sender
.
I suggest you do not use keyboard input to perform button clicks. Instead you should direct your keyboard input directly to the operand variable. The same thing should be done by buttons' Click event handler too.
Upvotes: 4
Reputation: 18013
You could use find control each time to get the button, but it would be better performance to add your known buttons to a dictionary of buttons for example. This also would not break if you rename a button and forget to update the code.
eg:
private Dictionary<char, Button> _buttons;
public Form1()
{
InitializeComponent();
this.KeyUp += Form1_KeyUp;
_buttons = new Dictionary<char, Button>();
_buttons.Add('0', btn0);
_buttons.Add('1', btn1);
_buttons.Add('2', btn2);
//etc
_buttons.Add('*', btnMultiply);
_buttons.Add('-', btnMinus);
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
char key = '1'; // Get your key char however you are doing it now
if (_buttons.ContainsKey(key))
_buttons[key].PerformClick();
}
Upvotes: 0
Reputation: 26446
Using the Name
property isn't wrong, but I personally don't like these secret links between a property and functionality of your application. Instead I would create a Dictionary<char, Button> mapping
, and populate it after InitializeComponent()
.
You can then use:
Button button;
if (mapping.TryGetValue(c, out button))
button.PerformClick();
Upvotes: 0
Reputation: 216273
You can get your button with a single line
Button b = this.Controls.OfType<Button>()
.FirstOrDefault(x => x.Name == "btn" + c.ToString());
if(b != null)
b.PerformClick();
This assumes that your buttons are named "btn1", "btn2", etc.. And I am talking about the Name property not the name you gave to the variable that represents your button.
Upvotes: 4