As the title says really. I\'ve had a look at inheriting from TextBox, but the only sensible override was \"OnKeyDown\", but that just gives me a key from the Key enum (with
I know it has been answered, but I found no proper solution that handles all special cases, most answers here swallows some important keys like Home, End, Tab, Shift+ any thing, ..etc.
So, I developed my own implementation as it may help somebody!
public class IntegerTextBox : TextBox
{
///
/// To be raised whenever integer value changed
///
public event EventHandler ValueChanged;
///
/// To restore if the user entered invalid characters
///
private int lastSavedValue = 0;
private int lastSelectionStart = 0;
private int lastSelectionLength = 0;
public int IntegerValue
{
get
{
//the default value is 0 if there is no text in the textbox
int value = 0;
int.TryParse(Text, out value);
return value;
}
set
{
if (this.Text.Trim() != value.ToString())
{
Text = value.ToString();
}
}
}
public IntegerTextBox()
: base()
{
this.LostFocus += (sender, e) =>
{
//if the user clears the text the text box and leaves it, set it to default value
if (string.IsNullOrWhiteSpace(this.Text))
IntegerValue = 0;
};
this.Loaded += (sender, e) =>
{
//populate the textbox with Initial IntegerValue (default = 0)
this.Text = this.IntegerValue.ToString();
};
this.TextChanged += (sender, e) =>
{
int newValue = 0;
if (int.TryParse(this.Text, out newValue)) //this will handle most cases like number exceeds the int max limits, negative numbers, ...etc.
{
if (string.IsNullOrWhiteSpace(Text) || lastSavedValue != newValue)
{
lastSavedValue = newValue;
//raise the event
EventHandler handler = ValueChanged;
if (handler != null)
handler(this, EventArgs.Empty);
}
}
else
{
//restore previous number
this.Text = lastSavedValue.ToString();
//restore selected text
this.SelectionStart = lastSelectionStart;
this.SelectionLength = lastSelectionLength;
}
};
this.KeyDown += (sender, e) =>
{
//before every key press, save selection start and length to handle overwriting selected numbers
lastSelectionStart = this.SelectionStart;
lastSelectionLength = this.SelectionLength;
};
}
}
The above code has a single disadvantage, TextChanged event will be raised frequently, but since we need an integer textbox, then we can rely on ValueChanged instead!