Feedback

C# - numerische TextBox

Veröffentlicht von am 10/14/2008
(2 Bewertungen)
Nachfolgend ein Steuerelement das nur numerische Eingabe zulässt.
/******************************************************************************
 * UserControl: TextBox die nur numerische Eingaben akzeptiert.
 * 
 * Version:		1.1.0 (10.10.2008)
 * Erstellt am: 30.09.2008
 * Autor:		Günther M. FOIDL
 * Copyright:   Nach österreichischem Urheberrecht geltent.
 *              Die Verwendung/Lizenzierung obliegt dem Autor.
 *              
 * Änderungen:
 * 1.1.0		Hinzufügen von OnlyPositive
 *				Validierung und anzeige durch ErrorProvider
 *****************************************************************************/
using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Forms;

namespace gfoidl.Tools.Controls
{
	/// <summary>
	/// TextBox die nur numerische Eingaben zulässt
	/// </summary>
	public class gfNumericTextBox : TextBox
	{
		#region Felder
		private ErrorProvider _errorProvider = new ErrorProvider();
		private bool _disposed = false;
		#endregion
		//---------------------------------------------------------------------
		#region Eigenschaften
		[DefaultValue(false)]
		[Description("Gibt an ob nur positive Werte erlaubt werden")]
		public bool OnlyPositive { get; set; }

		[DefaultValue(false)]
		[Description("Gibt an ob Leerzeichen akzeptiert werden")]
		public bool AllowSpace { get; set; }

		[DefaultValue(true)]
		[Description(
			"Gibt an ob das Einfügen über die Zwischenablage erlaubt ist")]
		public bool AllowPaste { get; set; }
		#endregion
		//---------------------------------------------------------------------
		#region Überschreibungen
		protected override void Dispose(bool disposing)
		{
			if (!_disposed)
			{
				_disposed = true;
				_errorProvider.Dispose();
				base.Dispose(disposing);

				GC.SuppressFinalize(this);
			}
		}
		//---------------------------------------------------------------------
		/// <summary>
		/// Erlaubt nur numerische Eingaben (HEX inklusive), 
		/// das Minuszeichen, den Dezimalpunkt und Bearbeitungszeichen
		/// (Backspace)
		/// </summary>
		/// <param name="e"></param>
		protected override void OnKeyPress(KeyPressEventArgs e)
		{
			base.OnKeyPress(e);

			NumberFormatInfo numberFormatInfo =
				CultureInfo.CurrentCulture.NumberFormat;
			string decimalSeperator = numberFormatInfo.NumberDecimalSeparator;
			string groupSeperator = numberFormatInfo.NumberGroupSeparator;
			string negativeSign = numberFormatInfo.NegativeSign;

			string keyInput = e.KeyChar.ToString();

			if (char.IsDigit(e.KeyChar))
			{
				// OK
			}
			else if ((keyInput.Equals(decimalSeperator)) ||
					(keyInput.Equals(groupSeperator)) ||
					(keyInput.Equals(negativeSign)))
			{
				// OK
			}
			else if (e.KeyChar == '\b')
			{
				// OK
			}
			else if (this.AllowSpace && e.KeyChar == ' ')
			{
				// OK
			}
			else
			{
				// ungültige Eingabe:
				e.Handled = true;
			}
		}
		//---------------------------------------------------------------------
		protected override void OnValidated(System.EventArgs e)
		{
			base.OnValidated(e);

			// Prüfen ob nur positive (0 inklusive) zulässig sind:
			if (this.Text.Contains("-") && this.OnlyPositive)
				_errorProvider.SetError(this, "Keine negativen Werte erlaubt");
			else
				_errorProvider.Clear();
		}
		//---------------------------------------------------------------------
		[Description(
			"Der dem Steuerelement zugeordnete Text. Nur numerische " +
			"Werte zulässig")]
		public override string Text
		{
			get
			{
				return base.Text;
			}
			set
			{
				bool digits = true;

				// Prüfen ob nur numerisch:
				foreach (char c in value)
					if (!(char.IsDigit(c) || c == '.' || c == ','))
					{
						digits = false;
						break;
					}

				// Wenn nur numerisch -> Eigenschaft setzen:
				if (digits)
					base.Text = value;
			}
		}
		//---------------------------------------------------------------------
		protected override void WndProc(ref Message m)
		{
			// Pasten prüfen:
			if (m.Msg == 0x0302)
			{
				foreach (char c in Clipboard.GetText())
				{
					if (!(char.IsDigit(c) || c == '.' || c == ','))
					{
						m.Result = IntPtr.Zero;
						return;
					}
				}
			}

			base.WndProc(ref m);
		}
		#endregion
		//---------------------------------------------------------------------
		#region Eigenschaften
		//---------------------------------------------------------------------
		/// <summary>
		/// Gibt den Inhalt als <c>int</c> zurück
		/// </summary>
		[Browsable(false)]
		public int IntValue
		{
			get
			{
				if (!string.IsNullOrEmpty(this.Text))
				{
					int i;
					if (int.TryParse(this.Text, out i))
						return i;
				}

				return 0;
			}
		}
		//---------------------------------------------------------------------
		/// <summary>
		/// Gibt den Inhalt als <c>float</c> zurück
		/// </summary>
		[Browsable(false)]
		public float FloatValue
		{
			get
			{
				if (!string.IsNullOrEmpty(this.Text))
				{
					float f;
					if (float.TryParse(this.Text, out f))
						return f;
				}

				return 0f;
			}
		}
		//---------------------------------------------------------------------
		/// <summary>
		/// Gibt den Inhalt als <c>double</c> zurück
		/// </summary>
		[Browsable(false)]
		public double DoubleValue
		{
			get
			{
				if (!string.IsNullOrEmpty(this.Text))
				{
					double d;
					if (double.TryParse(this.Text, out d))
						return d;
				}

				return 0;
			}
		}
		//---------------------------------------------------------------------
		/// <summary>
		/// Gibt den Inhalt als <c>decimal</c> zurück
		/// </summary>
		[Browsable(false)]
		public decimal DecimalValue
		{
			get
			{
				if (!string.IsNullOrEmpty(this.Text))
				{
					decimal d;
					if (decimal.TryParse(this.Text, out d))
						return d;
				}

				return 0;
			}
		}
		#endregion
	}
}

3 Kommentare zum Snippet

Günther Foidl schrieb am 10/14/2008:
Änderung:
if (this.Text.Contains("-"))

ersetzt durch:
if (this.Text.Contains("-") && this.OnlyPositive)
Günther Foidl schrieb am 10/14/2008:
Durch einen Tipp von Ralf Jansen wird jetz auch das Einfügen von der Zwischenablage geprüft.
Günther Foidl schrieb am 12/2/2008:
Das von dir vorgeschlagenen ist auch ein Möglichkeit - ich hab mich für diese Variante entschieden.

e.Handled = true; bedeutet dass das Ereignis als behandelt markiert wird und somit nicht weiterverarbeitet wird.
 

Logge dich ein, um hier zu kommentieren!