diff -r 3145aadca3d2 -r 0c551e8818e0 External/Aga.Controls/NumericTextBox.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/External/Aga.Controls/NumericTextBox.cs Sun May 27 15:16:19 2012 +0000 @@ -0,0 +1,189 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; +using System.Globalization; + + +namespace Aga.Controls +{ + /// + /// Restricts the entry of characters to digits, the negative sign, + /// the decimal point, and editing keystrokes (backspace). + /// It does not handle the AltGr key so any keys that can be created in any + /// combination with AltGr these are not filtered + /// + public class NumericTextBox : TextBox + { + private const int WM_PASTE = 0x302; + private NumberStyles numberStyle = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign; + + /// + /// Restricts the entry of characters to digits, the negative sign, + /// the decimal point, and editing keystrokes (backspace). + /// It does not handle the AltGr key + /// + /// + protected override void OnKeyPress(KeyPressEventArgs e) + { + base.OnKeyPress(e); + + e.Handled = invalidNumeric(e.KeyChar); + } + + + /// + /// Main method for verifying allowed keypresses. + /// This does not catch cut paste copy ... operations. + /// + /// + /// + private bool invalidNumeric(char key) + { + bool handled = false; + + NumberFormatInfo numberFormatInfo = CultureInfo.CurrentCulture.NumberFormat; + string decimalSeparator = numberFormatInfo.NumberDecimalSeparator; + string negativeSign = numberFormatInfo.NegativeSign; + + string keyString = key.ToString(); + + if (Char.IsDigit(key)) + { + // Digits are OK + } + else if (AllowDecimalSeparator && keyString.Equals(decimalSeparator)) + { + if (Text.IndexOf(decimalSeparator) >= 0) + { + handled = true; + } + } + else if (AllowNegativeSign && keyString.Equals(negativeSign)) + { + if (Text.IndexOf(negativeSign) >= 0) + { + handled = true; + } + } + else if (key == '\b') + { + // Backspace key is OK + } + else if ((ModifierKeys & (Keys.Control)) != 0) + { + // Let the edit control handle control and alt key combinations + } + else + { + // Swallow this invalid key and beep + handled = true; + } + return handled; + } + + + /// + /// Method invoked when Windows sends a message. + /// + /// Message from Windows. + /// + /// This is over-ridden so that the user can not use + /// cut or paste operations to bypass the TextChanging event. + /// This catches ContextMenu Paste, Shift+Insert, Ctrl+V, + /// While it is generally frowned upon to override WndProc, no + /// other simple mechanism was apparent to simultaneously and + /// transparently intercept so many different operations. + /// + protected override void WndProc(ref Message m) + { + // Switch to handle message... + switch (m.Msg) + { + case WM_PASTE: + { + // Get clipboard object to paste + IDataObject clipboardData = Clipboard.GetDataObject(); + + // Get text from clipboard data + string pasteText = (string)clipboardData.GetData( + DataFormats.UnicodeText); + + // Get the number of characters to replace + int selectionLength = SelectionLength; + + // If no replacement or insertion, we are done + if (pasteText.Length == 0) + { + break; + } + else if (selectionLength != 0) + { + base.Text = base.Text.Remove(SelectionStart, selectionLength); + } + + bool containsInvalidChars = false; + foreach (char c in pasteText) + { + if (containsInvalidChars) + { + break; + } + else if (invalidNumeric(c)) + { + containsInvalidChars = true; + } + } + + if (!containsInvalidChars) + { + base.Text = base.Text.Insert(SelectionStart, pasteText); + } + + return; + } + + } + base.WndProc(ref m); + } + + + public int IntValue + { + get + { + int intValue; + Int32.TryParse(this.Text, numberStyle, CultureInfo.CurrentCulture.NumberFormat, out intValue); + return intValue; + } + } + + public decimal DecimalValue + { + get + { + decimal decimalValue; + Decimal.TryParse(this.Text, numberStyle, CultureInfo.CurrentCulture.NumberFormat, out decimalValue); + return decimalValue; + } + } + + + private bool allowNegativeSign; + [DefaultValue(true)] + public bool AllowNegativeSign + { + get { return allowNegativeSign; } + set { allowNegativeSign = value; } + } + + private bool allowDecimalSeparator; + [DefaultValue(true)] + public bool AllowDecimalSeparator + { + get { return allowDecimalSeparator; } + set { allowDecimalSeparator = value; } + } + + } + +}