Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Textbox InputMask Like in VFP
Message
From
21/04/2008 01:20:49
 
General information
Forum:
ASP.NET
Category:
Forms
Environment versions
OS:
Windows XP SP2
Network:
Windows 2003 Server
Database:
MS SQL Server
Miscellaneous
Thread ID:
01311984
Message ID:
01312010
Views:
19
>There is a way to simulate in .Net the VFP TextBox behavior when it manipulate numeric values applying an InputMask like "9999.99" ?
>
>For example it has to position on the decimal numbers when a period is introduced.
>
>I test the MaskedTextBox but it does not function like VFP TextBox do with numeric values.


The built-in MaskedTextBox doesn't work too well (unless it's been fixed in .NET 2.0, I haven't used it because I've got one I've been using since 1.1).

This example has been subclassed from MyTextBox subclass and will need additional tweaking if you want to sub-class from the System.Windows.Forms.TextBox. In particular notice that all the eventhandlers are overridden from the parent class. But other than that minor tweaking, this should work just fine.
	public class MyNumericTextBox : MyTextBox
	{
		#region Declarations
		private int m_DecimalPlaces = 0;
		private decimal m_Maximum = 100;
		private decimal m_Minimum = 0;
		protected char[] AllowedChars = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-'};
		protected string m_FormatString = "##0";
		private bool m_DisplayDefaultZero = true;
		#endregion

		#region Constructor
		public MyNumericTextBox()
		{
			this.MaxLength = 3;
			this.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
		}
		#endregion

		#region Methods
		public void SetText(object val)
		{
			if (this.m_Minimum > 0)
			{
				if (val is Decimal)
					this.Text = ((decimal)val).ToString(this.m_FormatString);
			}
			else
			{
				if (val is int)
					this.Text = ((int)val).ToString(this.m_FormatString);
			}
		}
		#endregion

		#region Events
		protected override void FormatHandler(object sender, ConvertEventArgs e)
		{
			if(this.DisplayDefaultZero) 
			{
				if (e.Value == System.DBNull.Value)
					e.Value = (int)0;
			}
			if (e.Value is Decimal && e.DesiredType == typeof(string))
				e.Value = ((decimal)e.Value).ToString(this.m_FormatString);
			else if (e.Value is int && e.DesiredType == typeof(string))
				e.Value = ((int)e.Value).ToString(this.m_FormatString);
		}
		protected override void ParseHandler(object sender, ConvertEventArgs e)
		{
			if (((string)e.Value).Trim().Length == 0)
				e.Value = "0";

			if (e.DesiredType == typeof(decimal))
				e.Value = Decimal.Parse((string)e.Value, System.Globalization.NumberStyles.Any);
			else if (e.DesiredType == typeof(int))
			{
				string[] s = ((string)e.Value).Trim().Split('.');
				e.Value = Decimal.Parse(s[0], System.Globalization.NumberStyles.Any);
			}
		}
		protected override void KeyPressHandler(object sender, KeyPressEventArgs e)
		{
			// Prevent illegal characters
			bool allowed = false;
			for (int i = 0; i < this.AllowedChars.Length; i++) 
			{
				if (e.KeyChar == this.AllowedChars[i])
				{
					allowed = true;
					break;
				}
			}

			if (allowed == true)
			{
				string CurrentText = this.Text;
				if (this.SelectionLength > 0)
				{
					int i = this.Text.IndexOf(this.SelectedText);
					int j = i + this.SelectionLength;

					if (i > 0 && j == this.TextLength)
						CurrentText = this.Text.Substring(0, i);
					else
					if (i > 0)
						CurrentText = this.Text.Substring(0, i) + this.Text.Substring(j);
					else
						CurrentText = this.Text.Substring(j);
				}
				if (CurrentText != this.SelectedText)
				{
					// Prevent duplicates of decimal point and minus sign
					if ((e.KeyChar == '.' || e.KeyChar == '-') && 
						CurrentText.IndexOf(e.KeyChar) >= 0)
						e.Handled = true;
					else
					{
						// Prevent too many digits on either side of decimal point
						if (this.m_DecimalPlaces > 0 && 
							e.KeyChar != '.' && e.KeyChar != '-' && e.KeyChar != (char)Keys.Back)
						{
							int MaxDecimalPos = this.MaxLength - this.m_DecimalPlaces - 1;
							int DecimalPos    = CurrentText.IndexOf('.');
							int DecimalDigits = CurrentText.Length - DecimalPos - 1;

							if (DecimalPos < 0)
							{
								if (CurrentText.Length >= MaxDecimalPos)
									e.Handled = true;
							}
							else
							if (this.SelectionStart <= DecimalPos)
							{
								if (DecimalPos == MaxDecimalPos)
									e.Handled = true;
							}
							else
							if (this.SelectionStart >= CurrentText.Length)
							{
								if (DecimalDigits == this.m_DecimalPlaces)
									e.Handled = true;
							}

//							if (DecimalPos > MaxDecimalPos)
//								e.Handled = true;
//							else
//							if (CurrentText.Length > DecimalPos + this.m_DecimalPlaces)
//								e.Handled = true;
						}
					}
				}
			}
			else
				e.Handled = true;
		}

		protected override void ValidatingHandler(object sender, CancelEventArgs e)
		{
			if (this.Text.Trim().Length == 0)
				return;

			try
			{
				decimal test = Decimal.Parse(this.Text);
				if (test > this.m_Maximum || test < this.m_Minimum)
				{
					string message = "The value for this field must be between " +
						this.m_Maximum.ToString() + " and " + this.m_Minimum.ToString() + "!";
					string caption = "Value out of range";
					MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);

					e.Cancel = true;
				}
			}
			catch (Exception ex)
			{
				System.Diagnostics.Debug.WriteLine(ex.Message);
			}
		}
		#endregion

		#region Properties
		[Description("The number of digits to display after the decimal.")]
		[DefaultValue(0)]
		public int DecimalPlaces
		{
			get {return this.m_DecimalPlaces;}
			set
			{
				this.m_DecimalPlaces = value;

				// Create the AllowedChars array for the KeyPress event handler
				if (value > 0 && this.m_Minimum < 0)
					this.AllowedChars = new char[] {(char)Keys.Back, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.', '-'};
				else if (value > 0)
					this.AllowedChars = new char[] {(char)Keys.Back, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.'};
				else if (this.m_Minimum < 0)
					this.AllowedChars = new char[] {(char)Keys.Back, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-'};
				else
					this.AllowedChars = new char[] {(char)Keys.Back, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};

				// Create the FormatString property value
				string[] format = this.m_FormatString.Split(new char[] {'.'}, 2);
				if (value > 0)
				{
					string s = new string('0', value);
					this.m_FormatString = format[0] + "." + s;
				}
				else
					this.m_FormatString = format[0];

				this.MaxLength = this.m_FormatString.Length;
				if (this.m_Minimum < 0 && this.m_Minimum.ToString().Length > this.m_Maximum.ToString().Length)
					this.MaxLength++;
			}
		}
		[Description("The maximum value allowed in the field.")]
		[DefaultValue(100)]
		public decimal Maximum
		{
			get {return this.m_Maximum;}
			set
			{
				if (value < this.m_Minimum)
					return;

				this.m_Maximum = value;

				// Create the first half of the FormatString property
				this.MaxLength = value.ToString().Length;
				int max = this.m_Minimum.ToString().Length;
				if (this.m_Minimum < 0 && max > this.MaxLength)
					this.MaxLength = max;

				if (this.MaxLength > 2 && value.ToString().Length < this.m_Minimum.ToString().Length)
					this.m_FormatString = new string('#', this.MaxLength - 2) + "0";
				else if (this.MaxLength > 1)
					this.m_FormatString = new string('#', this.MaxLength - 1) + "0";
				else
					this.m_FormatString = "0";

//				if (this.m_Minimum < 0)
//					this.m_FormatString = "-" + this.m_FormatString;

				// Finally, create the formatting
				this.DecimalPlaces = this.m_DecimalPlaces;
			}
		}
		[Description("The minimum value allowed in the field.")]
		[DefaultValue(0)]
		public decimal Minimum
		{
			get {return this.m_Minimum;}
			set
			{
				if (value > this.m_Maximum)
					return;
				
				this.m_Minimum = value;
				this.Maximum = this.m_Maximum;
			}
		}

		[Description("Enable if you don't want to display a zero in this field")]
		public bool DisplayDefaultZero
		{
			get {return this.m_DisplayDefaultZero;}
			set {this.m_DisplayDefaultZero = value;}
		}
//		[Description("The string to use with ToString to format.")]
//		[DefaultValue("##0")]
//		public string FormatString
//		{
//			get {return this.m_FormatString;}
//			set {this.m_FormatString = value;}
//		}
		#endregion
	}
I notice now that I have some things commented out ... I wrote this little sample a long time ago and I don't remember why the stuff is commented out. But try it anyway ... I'm sure it'll give you 99% of what you need.

~~Bonnie
Bonnie Berent DeWitt
NET/C# MVP since 2003

http://geek-goddess-bonnie.blogspot.com
Previous
Reply
Map
View

Click here to load this message in the networking platform