我想创建一个只接受特定范围内的数值的TextBox。 实现此类TextBox的最佳方法是什么?
我考虑过派生TextBox并覆盖TextProperty的验证和强制。但是,我不知道如何做到这一点,我知道通常不建议派生WPF控件。
<小时/> 修改:
private void textBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
int result;
if (!validateStringAsNumber(e.Text,out result,false))
{
e.Handled = true;
}
}
(validateStringAsNumber是我的主要使用Int.TryParse的函数)
一些建议的解决方案可能更好,但是对于我需要的简单功能,这个解决方案是最容易和最快的,同时足以满足我的需求。
答案 0 :(得分:8)
到目前为止,我见过的大多数实现都使用PreviewTextInput事件来实现正确的掩码行为。 This one继承自TextBox,this one使用附加属性。两者都使用.Net的MaskedTextProvider来提供正确的掩码行为,但是如果你只想要一个简单的“仅限数字”文本框,则不需要这个类。
答案 1 :(得分:5)
private void txt_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
int iValue = -1;
if (Int32.TryParse(textBox.Text, out iValue) == false)
{
TextChange textChange = e.Changes.ElementAt<TextChange>(0);
int iAddedLength = textChange.AddedLength;
int iOffset = textChange.Offset;
textBox.Text = textBox.Text.Remove(iOffset, iAddedLength);
}
}
答案 2 :(得分:4)
我认为,满足此要求的最佳方法是仅使用OnTextChanged
事件,因为它可以处理按键的数字,也可以从剪贴板处理复制+粘贴。我希望下面显示的VB代码可以为此提供一些启示。
Private Sub NumericBox_TextChanged(sender As Object, e As TextChangedEventArgs) Handles Me.TextChanged
Dim Buffer As New StringBuilder
Dim Index As Integer = Me.SelectionStart
For Each C In Me.Text
If Char.IsDigit(C) Then
Buffer.Append(C)
ElseIf Me.SelectionStart > Buffer.Length Then
Index -= 1
End If
Next
Me.Text = Buffer.ToString
Me.SelectionStart = Index
End Sub
答案 3 :(得分:0)
总体上最好的原因是为文本框使用覆盖方法OnKeyPressed
。以下是使用静态Char方法IsDigit
覆盖的代码。
if (!Char.IsDigit(e.KeyChar) && !Char.IsControl(e.KeyChar)) e.Handled = true;
这就是你真正需要做的一切。
答案 4 :(得分:0)
这是我首选的方法:
private void yearTxt_PreviewKeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.D0:
case Key.D1:
case Key.D2:
case Key.D3:
case Key.D4:
case Key.D5:
case Key.D6:
case Key.D7:
case Key.D8:
case Key.D9:
case Key.NumLock:
case Key.NumPad0:
case Key.NumPad1:
case Key.NumPad2:
case Key.NumPad3:
case Key.NumPad4:
case Key.NumPad5:
case Key.NumPad6:
case Key.NumPad7:
case Key.NumPad8:
case Key.NumPad9:
case Key.Back:
break;
default:
e.Handled = true;
break;
}
}