#realJSOP
Самый простой способ-это справиться с TextChanged
событие для текстового поля, чтобы оценить текст, введенный при каждом нажатии клавиши. Вам нужно будет отфильтровать любой символ, который не является числовым, а также проверить int.Parse
- значение d, чтобы убедиться,что оно попадает в диапазон.
Более сложные способы включают в себя создание нового класса, производного от TextBox, который позволяет программисту ограничивать ввод только числовыми значениями, А также указывать допустимые диапазоны. Если вы хотите пойти по этому пути, вы можете найти что-то с помощью не слишком тщательно разработанного поиска google.
Вот один из них, над которым я работаю. Я не могу гарантировать полноту или пригодность, но это может обеспечить разумную отправную точку.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using BODCommon;
using ObjectExtensions;
namespace WPFCommon.Controls
{
/// <summary>
///
/// </summary>
public class TextBoxNumeric : TextBox
{
#region Enumerators
/// <summary>
/// The types of numeric values that can be entered with this control
/// </summary>
public enum NumericTypes
{
/// <summary>
/// Any integer value (see comments for GetNumericValue nmethods)
/// </summary>
Integer,
/// <summary>
/// Any decimal value
/// </summary>
Decimal,
/// <summary>
/// Any floating point value (see comments for GetNumericValue nmethods)
/// </summary>
Double
}
#endregion Enumerators
#region Fields
private bool eventHooked = false;
private string thisText = string.Empty;
#endregion Fields
#region Attached properties
/// <summary>
/// Gets or sets the type of the numeric value to be entered.
/// </summary>
public NumericTypes NumericType
{
get { return (NumericTypes)this.GetValue(NumericTypeProperty); }
set { this.SetValue(NumericTypeProperty, value); }
}
/// <summary>
/// Gets or sets the precision value.
/// </summary>
public int PrecisionValue
{
get { return (int)this.GetValue(PrecisionValueProperty); }
set { this.SetValue(PrecisionValueProperty, value); }
}
/// <summary>
/// The numeric type attached property
/// </summary>
public static readonly DependencyProperty NumericTypeProperty = DependencyProperty.Register("NumericType", typeof(NumericTypes), typeof(TextBoxNumeric), new PropertyMetadata(NumericTypes.Double));
/// <summary>
/// The precision attached property
/// </summary>
public static readonly DependencyProperty PrecisionValueProperty = DependencyProperty.Register("PrecisionValue", typeof(int), typeof(TextBoxNumeric), new PropertyMetadata(2));
#endregion Attached properties
#region Constructor/destructor
/// <summary>
/// Initializes the <see cref="TextBoxNumeric"/> class.
/// </summary>
static TextBoxNumeric()
{
}
/// <summary>
/// Finalizes an instance of the <see cref="TextBoxNumeric"/> class.
/// </summary>
~TextBoxNumeric()
{
if (this.eventHooked)
{
// unhook the preview event
this.PreviewTextInput += TextBoxNumeric_PreviewTextInput;
}
}
#endregion Constructor/destructor
/// <summary>
/// Is called when a control template is applied.
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (!this.eventHooked)
{
this.eventHooked = true;
this.PreviewTextInput += TextBoxNumeric_PreviewTextInput;
}
}
/// <summary>
/// Handles the PreviewTextInput event of the TextBoxNumeric control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="TextCompositionEventArgs"/> instance containing the event data.</param>
private void TextBoxNumeric_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
switch (this.NumericType)
{
case NumericTypes.Integer : this.PreviewAsInteger(ref e); break;
case NumericTypes.Double : this.PreviewAsDouble(ref e); break;
case NumericTypes.Decimal : this.PreviewAsDecimal(ref e); break;
}
}
/// <summary>
/// Previews as integer.
/// </summary>
/// <param name="e">The <see cref="TextCompositionEventArgs"/> instance containing the event data.</param>
private void PreviewAsInteger(ref TextCompositionEventArgs e)
{
string text = e.Text;
TextBox textbox = (TextBox)(e.Source);
if (!text.IsNumeric())
{
e.Handled = true;
}
if (!e.Handled)
{
//this.GetTextBoxText(textbox, ref text);
}
}
/// <summary>
/// Previews as double.
/// </summary>
/// <param name="e">The <see cref="TextCompositionEventArgs"/> instance containing the event data.</param>
private void PreviewAsDouble(ref TextCompositionEventArgs e)
{
string text = e.Text;
TextBox textbox = (TextBox)(e.Source);
bool hasDecimal = textbox.Text.IndexOf(".") >= 0;
if (text == ".")
{
if (hasDecimal)
{
e.Handled = true;
}
else
{
hasDecimal = true;
}
}
else if (text != "." && !text.IsNumeric())
{
e.Handled = true;
}
if (!e.Handled)
{
this.GetTextBoxText(textbox, ref text);
int decLength = text.Length - ((hasDecimal) ? text.IndexOf(".") + 1 : 0);
if (hasDecimal && decLength > this.PrecisionValue)
{
e.Handled = true;
}
}
}
/// <summary>
/// Previews as decimal.
/// </summary>
/// <param name="e">The <see cref="TextCompositionEventArgs"/> instance containing the event data.</param>
private void PreviewAsDecimal(ref TextCompositionEventArgs e)
{
string text = e.Text;
TextBox textbox = (TextBox)(e.Source);
bool hasDecimal = textbox.Text.IndexOf(".") >= 0;
if (text == "." && hasDecimal)
{
e.Handled = true;
}
else if (text != "." && !text.IsNumeric())
{
e.Handled = true;
}
if (!e.Handled)
{
this.GetTextBoxText(textbox, ref text);
int decLength = text.Length - ((hasDecimal) ? text.IndexOf(".") + 1 : 0);
if (hasDecimal && decLength > this.PrecisionValue)
{
e.Handled = true;
}
}
}
/// <summary>
/// Gets the text box text for the preview methods.
/// </summary>
/// <param name="textbox">The textbox.</param>
/// <param name="text">The text.</param>
private void GetTextBoxText(TextBox textbox, ref string text)
{
int pos = textbox.SelectionStart;
if (pos == 0)
{
text = string.Format("{0}{1}", text, textbox.Text);
}
else if (pos == textbox.Text.Length)
{
text = string.Format("{0}{1}", textbox.Text, text);
}
else
{
List<char> chars = new List<char>();
chars.AddRange(textbox.Text.ToArray());
chars.InsertRange(pos, text.ToArray());
text = string.Empty;
foreach(char c in chars)
{
text += c;
}
}
}
/// <summary>
/// <para>Gets the numeric value respresented by the text. If you need to assign the return value to something other</para>
/// <para>than an int, double or decimal, you'll have to cast the return value to the desired type. Optionally, you </para>
/// <para>can add appropriate code to this class to add support for the desired numeric type(s).</para>
/// <para> </para>
/// <para>Usage is:</para>
/// <para> double value = textbox.GetNumericValue<double>();</para>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ignoreException">if set to <c>true