External/Aga.Controls/NumericTextBox.cs
author StephaneLenclud
Sun, 03 Feb 2013 18:01:50 +0100
branchMiniDisplay
changeset 433 090259cfd699
permissions -rw-r--r--
Adding SoundGraphDisplay and SensorFrontView classes.
They were respectively based on SystemTray and SensorNotifyIcon.
SoundGraphDisplay is now able to load iMONDisplay.dll providing it lives on your PATH.
Adding option to sensor context menu for adding it into FrontView.
     1 using System;
     2 using System.ComponentModel;
     3 using System.Windows.Forms;
     4 using System.Globalization;
     5 
     6 
     7 namespace Aga.Controls
     8 {
     9 	/// <summary>
    10 	/// Restricts the entry of characters to digits, the negative sign,
    11 	/// the decimal point, and editing keystrokes (backspace).
    12 	/// It does not handle the AltGr key so any keys that can be created in any
    13 	/// combination with AltGr these are not filtered
    14 	/// </summary>
    15 	public class NumericTextBox : TextBox
    16 	{
    17 		private const int WM_PASTE = 0x302;
    18 		private NumberStyles numberStyle = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign;
    19 
    20 		/// <summary>
    21 		/// Restricts the entry of characters to digits, the negative sign,
    22 		/// the decimal point, and editing keystrokes (backspace).
    23 		/// It does not handle the AltGr key
    24 		/// </summary>
    25 		/// <param name="e"></param>
    26 		protected override void OnKeyPress(KeyPressEventArgs e)
    27 		{
    28 			base.OnKeyPress(e);
    29 
    30 			e.Handled = invalidNumeric(e.KeyChar);
    31 		}
    32 
    33 
    34 		/// <summary>
    35 		/// Main method for verifying allowed keypresses.
    36 		/// This does not catch cut paste copy ... operations.
    37 		/// </summary>
    38 		/// <param name="key"></param>
    39 		/// <returns></returns>
    40 		private bool invalidNumeric(char key)
    41 		{
    42 			bool handled = false;
    43 
    44 			NumberFormatInfo numberFormatInfo = CultureInfo.CurrentCulture.NumberFormat;
    45 			string decimalSeparator = numberFormatInfo.NumberDecimalSeparator;
    46 			string negativeSign = numberFormatInfo.NegativeSign;
    47 
    48 			string keyString = key.ToString();
    49 
    50 			if (Char.IsDigit(key))
    51 			{
    52 				// Digits are OK
    53 			}
    54 			else if (AllowDecimalSeparator && keyString.Equals(decimalSeparator))
    55 			{
    56 				if (Text.IndexOf(decimalSeparator) >= 0)
    57 				{
    58 					handled = true;
    59 				}
    60 			}
    61 			else if (AllowNegativeSign && keyString.Equals(negativeSign))
    62 			{
    63 				if (Text.IndexOf(negativeSign) >= 0)
    64 				{
    65 					handled = true;
    66 				}
    67 			}
    68 			else if (key == '\b')
    69 			{
    70 				// Backspace key is OK
    71 			}
    72 			else if ((ModifierKeys & (Keys.Control)) != 0)
    73 			{
    74 				// Let the edit control handle control and alt key combinations
    75 			}
    76 			else
    77 			{
    78 				// Swallow this invalid key and beep
    79 				handled = true;
    80 			}
    81 			return handled;
    82 		}
    83 
    84 
    85 		/// <summary>
    86 		/// Method invoked when Windows sends a message.
    87 		/// </summary>
    88 		/// <param name="m">Message from Windows.</param>
    89 		/// <remarks>
    90 		/// This is over-ridden so that the user can not use
    91 		/// cut or paste operations to bypass the TextChanging event.
    92 		/// This catches ContextMenu Paste, Shift+Insert, Ctrl+V,
    93 		/// While it is generally frowned upon to override WndProc, no
    94 		/// other simple mechanism was apparent to simultaneously and
    95 		/// transparently intercept so many different operations.
    96 		/// </remarks>
    97 		protected override void WndProc(ref Message m)
    98 		{
    99 			// Switch to handle message...
   100 			switch (m.Msg)
   101 			{
   102 				case WM_PASTE:
   103 					{
   104 						// Get clipboard object to paste
   105 						IDataObject clipboardData = Clipboard.GetDataObject();
   106 
   107 						// Get text from clipboard data
   108 						string pasteText = (string)clipboardData.GetData(
   109 								DataFormats.UnicodeText);
   110 
   111 						// Get the number of characters to replace
   112 						int selectionLength = SelectionLength;
   113 
   114 						// If no replacement or insertion, we are done
   115 						if (pasteText.Length == 0)
   116 						{
   117 							break;
   118 						}
   119 						else if (selectionLength != 0)
   120 						{
   121 							base.Text = base.Text.Remove(SelectionStart, selectionLength);
   122 						}
   123 
   124 						bool containsInvalidChars = false;
   125 						foreach (char c in pasteText)
   126 						{
   127 							if (containsInvalidChars)
   128 							{
   129 								break;
   130 							}
   131 							else if (invalidNumeric(c))
   132 							{
   133 								containsInvalidChars = true;
   134 							}
   135 						}
   136 
   137 						if (!containsInvalidChars)
   138 						{
   139 							base.Text = base.Text.Insert(SelectionStart, pasteText);
   140 						}
   141 
   142 						return;
   143 					}
   144 
   145 			}
   146 			base.WndProc(ref m);
   147 		}
   148 
   149 
   150 		public int IntValue
   151 		{
   152 			get
   153 			{
   154 				int intValue;
   155 				Int32.TryParse(this.Text, numberStyle, CultureInfo.CurrentCulture.NumberFormat, out intValue);
   156 				return intValue;
   157 			}
   158 		}
   159 
   160 		public decimal DecimalValue
   161 		{
   162 			get
   163 			{
   164 				decimal decimalValue;
   165 				Decimal.TryParse(this.Text, numberStyle, CultureInfo.CurrentCulture.NumberFormat, out decimalValue);
   166 				return decimalValue;
   167 			}
   168 		}
   169 
   170 
   171 		private bool allowNegativeSign;
   172 		[DefaultValue(true)]
   173 		public bool AllowNegativeSign
   174 		{
   175 			get { return allowNegativeSign; }
   176 			set { allowNegativeSign = value; }
   177 		}
   178 
   179 		private bool allowDecimalSeparator;
   180 		[DefaultValue(true)]
   181 		public bool AllowDecimalSeparator
   182 		{
   183 			get { return allowDecimalSeparator; }
   184 			set { allowDecimalSeparator = value; }
   185 		}
   186 
   187 	}
   188 
   189 }