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