1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/External/Aga.Controls/NumericTextBox.cs Sun May 27 15:16:19 2012 +0000
1.3 @@ -0,0 +1,189 @@
1.4 +using System;
1.5 +using System.ComponentModel;
1.6 +using System.Windows.Forms;
1.7 +using System.Globalization;
1.8 +
1.9 +
1.10 +namespace Aga.Controls
1.11 +{
1.12 + /// <summary>
1.13 + /// Restricts the entry of characters to digits, the negative sign,
1.14 + /// the decimal point, and editing keystrokes (backspace).
1.15 + /// It does not handle the AltGr key so any keys that can be created in any
1.16 + /// combination with AltGr these are not filtered
1.17 + /// </summary>
1.18 + public class NumericTextBox : TextBox
1.19 + {
1.20 + private const int WM_PASTE = 0x302;
1.21 + private NumberStyles numberStyle = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign;
1.22 +
1.23 + /// <summary>
1.24 + /// Restricts the entry of characters to digits, the negative sign,
1.25 + /// the decimal point, and editing keystrokes (backspace).
1.26 + /// It does not handle the AltGr key
1.27 + /// </summary>
1.28 + /// <param name="e"></param>
1.29 + protected override void OnKeyPress(KeyPressEventArgs e)
1.30 + {
1.31 + base.OnKeyPress(e);
1.32 +
1.33 + e.Handled = invalidNumeric(e.KeyChar);
1.34 + }
1.35 +
1.36 +
1.37 + /// <summary>
1.38 + /// Main method for verifying allowed keypresses.
1.39 + /// This does not catch cut paste copy ... operations.
1.40 + /// </summary>
1.41 + /// <param name="key"></param>
1.42 + /// <returns></returns>
1.43 + private bool invalidNumeric(char key)
1.44 + {
1.45 + bool handled = false;
1.46 +
1.47 + NumberFormatInfo numberFormatInfo = CultureInfo.CurrentCulture.NumberFormat;
1.48 + string decimalSeparator = numberFormatInfo.NumberDecimalSeparator;
1.49 + string negativeSign = numberFormatInfo.NegativeSign;
1.50 +
1.51 + string keyString = key.ToString();
1.52 +
1.53 + if (Char.IsDigit(key))
1.54 + {
1.55 + // Digits are OK
1.56 + }
1.57 + else if (AllowDecimalSeparator && keyString.Equals(decimalSeparator))
1.58 + {
1.59 + if (Text.IndexOf(decimalSeparator) >= 0)
1.60 + {
1.61 + handled = true;
1.62 + }
1.63 + }
1.64 + else if (AllowNegativeSign && keyString.Equals(negativeSign))
1.65 + {
1.66 + if (Text.IndexOf(negativeSign) >= 0)
1.67 + {
1.68 + handled = true;
1.69 + }
1.70 + }
1.71 + else if (key == '\b')
1.72 + {
1.73 + // Backspace key is OK
1.74 + }
1.75 + else if ((ModifierKeys & (Keys.Control)) != 0)
1.76 + {
1.77 + // Let the edit control handle control and alt key combinations
1.78 + }
1.79 + else
1.80 + {
1.81 + // Swallow this invalid key and beep
1.82 + handled = true;
1.83 + }
1.84 + return handled;
1.85 + }
1.86 +
1.87 +
1.88 + /// <summary>
1.89 + /// Method invoked when Windows sends a message.
1.90 + /// </summary>
1.91 + /// <param name="m">Message from Windows.</param>
1.92 + /// <remarks>
1.93 + /// This is over-ridden so that the user can not use
1.94 + /// cut or paste operations to bypass the TextChanging event.
1.95 + /// This catches ContextMenu Paste, Shift+Insert, Ctrl+V,
1.96 + /// While it is generally frowned upon to override WndProc, no
1.97 + /// other simple mechanism was apparent to simultaneously and
1.98 + /// transparently intercept so many different operations.
1.99 + /// </remarks>
1.100 + protected override void WndProc(ref Message m)
1.101 + {
1.102 + // Switch to handle message...
1.103 + switch (m.Msg)
1.104 + {
1.105 + case WM_PASTE:
1.106 + {
1.107 + // Get clipboard object to paste
1.108 + IDataObject clipboardData = Clipboard.GetDataObject();
1.109 +
1.110 + // Get text from clipboard data
1.111 + string pasteText = (string)clipboardData.GetData(
1.112 + DataFormats.UnicodeText);
1.113 +
1.114 + // Get the number of characters to replace
1.115 + int selectionLength = SelectionLength;
1.116 +
1.117 + // If no replacement or insertion, we are done
1.118 + if (pasteText.Length == 0)
1.119 + {
1.120 + break;
1.121 + }
1.122 + else if (selectionLength != 0)
1.123 + {
1.124 + base.Text = base.Text.Remove(SelectionStart, selectionLength);
1.125 + }
1.126 +
1.127 + bool containsInvalidChars = false;
1.128 + foreach (char c in pasteText)
1.129 + {
1.130 + if (containsInvalidChars)
1.131 + {
1.132 + break;
1.133 + }
1.134 + else if (invalidNumeric(c))
1.135 + {
1.136 + containsInvalidChars = true;
1.137 + }
1.138 + }
1.139 +
1.140 + if (!containsInvalidChars)
1.141 + {
1.142 + base.Text = base.Text.Insert(SelectionStart, pasteText);
1.143 + }
1.144 +
1.145 + return;
1.146 + }
1.147 +
1.148 + }
1.149 + base.WndProc(ref m);
1.150 + }
1.151 +
1.152 +
1.153 + public int IntValue
1.154 + {
1.155 + get
1.156 + {
1.157 + int intValue;
1.158 + Int32.TryParse(this.Text, numberStyle, CultureInfo.CurrentCulture.NumberFormat, out intValue);
1.159 + return intValue;
1.160 + }
1.161 + }
1.162 +
1.163 + public decimal DecimalValue
1.164 + {
1.165 + get
1.166 + {
1.167 + decimal decimalValue;
1.168 + Decimal.TryParse(this.Text, numberStyle, CultureInfo.CurrentCulture.NumberFormat, out decimalValue);
1.169 + return decimalValue;
1.170 + }
1.171 + }
1.172 +
1.173 +
1.174 + private bool allowNegativeSign;
1.175 + [DefaultValue(true)]
1.176 + public bool AllowNegativeSign
1.177 + {
1.178 + get { return allowNegativeSign; }
1.179 + set { allowNegativeSign = value; }
1.180 + }
1.181 +
1.182 + private bool allowDecimalSeparator;
1.183 + [DefaultValue(true)]
1.184 + public bool AllowDecimalSeparator
1.185 + {
1.186 + get { return allowDecimalSeparator; }
1.187 + set { allowDecimalSeparator = value; }
1.188 + }
1.189 +
1.190 + }
1.191 +
1.192 +}