Some guy asked a question:
Is there any other way to use a routine on InitilizeCompent to handle all textboxes?
So he wants to get away from typing a lot: no need to write the same event to all our textboxes on the windows form application (and this is true for every object who wants to subscribe to an event, not only winform applications of course).
An object can subscribe to any number of events and vice-versa: to an event any number of objects can be subscribed.
He has two events: KeyPress and Leave and many textboxes. Let me show you these events and I’ll show the simplier and better clean solution.
private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { char ch = e.KeyChar; decimal x; if (ch == (char)Keys.Back) { e.Handled = false; } else if (!char.IsDigit(ch) && ch != '.' || !Decimal.TryParse(textBox1.Text + ch, out x)) { e.Handled = true; } } private void textBox1_Leave(object sender, EventArgs e) { if (textBox1.Text == "") { MessageBox.Show("Please enter Num 1"); return; } else { textBox1.Text = Convert.ToDecimal(textBox1.Text).ToString("#,##"); } }
First of all I suggest you to read my Events and Delegates post here to get a bit more familiar with them.
If you read through those 2 posts you should know what is “sender” stands for: the object that raises the event. So let’s become more generic and try to cast the sender.
This version will fulfill your requirements:
private void AllTextBox_KeyPress(object sender, KeyPressEventArgs e) { TextBox tb = sender as TextBox; if (tb == null) { MessageBox.Show(@"KeyPress event was not fired by a TextBox!"); e.Handled = true; return; } char ch = e.KeyChar; decimal x; if (!char.IsDigit(ch) && ch != '.' || !decimal.TryParse(tb.Text + ch, out x)) { e.Handled = true; } } private void AllTextBox_Leave(object sender, EventArgs e) { TextBox tb = sender as TextBox; if (tb == null) { MessageBox.Show(@"Leave event was not fired by a TextBox!"); return; } if (string.IsNullOrEmpty(tb.Text)) { MessageBox.Show(@"Please enter Num 1"); return; } tb.Text = decimal.Parse(tb.Text).ToString("n2"); }
Before starting to use them, let’s walk through line by line.
In the KeyPress event first we try to cast the sender to TextBox. You may ask, why did I use this casting and not this one:
TextBox tb = (TextBox)sender;
Because this second version of casting throws runtime exception while using the as keyword won’t.
If the sender was not a TextBox (for example a ComboBox) the casting results null, we show a message box, drop the entered character and exit the method.
The rest is the same: if a number was entered we show it in the textbox, otherwise it’ll be dropped (no need to set the e.Handler to false, it is its starting statement at event handler initialization).
One more thing: I used ToString(“n2”) because it will use thousand separators depending on your computer culture. Much better conversion but it’s up to you.
Now you can subscribe to these events either in designer mode of the Visual Studio or programmatically. I show you the second version:
public Form1() { InitializeComponent(); textBox1.KeyPress += AllTextBox_KeyPress; textBox1.Leave += AllTextBox_Leave; textBox2.KeyPress += AllTextBox_KeyPress; textBox2.Leave += AllTextBox_Leave; comboBox1.KeyPress += AllTextBox_KeyPress; comboBox1.Leave += AllTextBox_Leave; }
You should drop 2 textboxes and 1 combobox to your form with these given names.
Try it. It works. Believe me. 🙂