C# 创建只接受数字的 WPF TextBox
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1226128/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Create WPF TextBox that accepts only numbers
提问by Elad
I would like to create a TextBox that only accepts numeric values, in a specific range. What is the best way to implement such TextBox?
我想创建一个只接受特定范围内的数值的 TextBox。实现此类 TextBox 的最佳方法是什么?
I thought about deriving TextBox and to override the validation and coercion of the TextProperty. However, I am not sure how to do this, and I understand that deriving WPF control is generally not recommended.
我想过派生 TextBox 并覆盖 TextProperty 的验证和强制。但是,我不确定如何执行此操作,并且我了解通常不推荐派生 WPF 控件。
Edit:编辑:
我需要的是一个非常基本的文本框,它可以过滤掉所有不是数字的按键。实现它的最简单方法是处理 TextBox.PreviewTextInput 事件:
private void textBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
int result;
if (!validateStringAsNumber(e.Text,out result,false))
{
e.Handled = true;
}
}
(validateStringAsNumber is my function that primarily use Int.TryParse)
(validateStringAsNumber 是我主要使用 Int.TryParse 的函数)
Some of the suggested solutions are probably better, but for the simple functionality I needed this solution is the easiest and quickest to implement while sufficient for my needs.
一些建议的解决方案可能更好,但对于我需要的简单功能,此解决方案是最容易和最快实施的,同时足以满足我的需求。
采纳答案by Lars Truijens
Most implementations I have seen so far are using the PreviewTextInputevent to implement the correct mask behavior. This oneinherits from TextBox and this oneuses attached properties. Both use .Net's MaskedTextProviderto provide the correct mask behaviour, but if you just want a simple 'numbers only' textbox you don't need this class.
到目前为止,我看到的大多数实现都使用PreviewTextInput事件来实现正确的掩码行为。这个继承自 TextBox,这个使用附加属性。两者都使用 .Net 的MaskedTextProvider来提供正确的掩码行为,但如果您只想要一个简单的“仅数字”文本框,则不需要此类。
回答by Robert
The overall best why is to use the override method OnKeyPressed
for the textbox like. Here is the code for the override using the static Char Method IsDigit
.
整体最好的原因是对OnKeyPressed
文本框使用覆盖方法。这是使用静态 Char Method 进行覆盖的代码IsDigit
。
if (!Char.IsDigit(e.KeyChar) && !Char.IsControl(e.KeyChar)) e.Handled = true;
That is all you really need to do.
这就是你真正需要做的。
回答by Nanda
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);
}
}
回答by Manta
In my humble opinion, the best way to fulfill this requirement is using only OnTextChanged
event because it can handle the digit from keystroke and also be able to handle Copy+Paste from clipboard too. I hope that my VB code shown below can throw some light on this.
在我看来,满足此要求的最佳方法是仅使用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
回答by Bryun
This would be my preferred approach:
这将是我的首选方法:
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;
}
}