我希望接受数字和小数点,但没有符号。
我已经看过使用Windows窗体中的NumericUpDown控件的示例,以及来自微软的这个NumericUpDown自定义控件的示例。但到目前为止,似乎NumericUpDown (WPF是否支持)不会提供我想要的功能。我的应用程序是这样设计的,任何头脑正常的人都不会想弄乱箭头。在我的应用程序中,它们没有任何实际意义。
所以我正在寻找一个简单的方法,使一个标准的WPF文本框只接受我想要的字符。这可能吗?实用吗?
我希望接受数字和小数点,但没有符号。
我已经看过使用Windows窗体中的NumericUpDown控件的示例,以及来自微软的这个NumericUpDown自定义控件的示例。但到目前为止,似乎NumericUpDown (WPF是否支持)不会提供我想要的功能。我的应用程序是这样设计的,任何头脑正常的人都不会想弄乱箭头。在我的应用程序中,它们没有任何实际意义。
所以我正在寻找一个简单的方法,使一个标准的WPF文本框只接受我想要的字符。这可能吗?实用吗?
当前回答
对于那些寻找一个快速和非常简单的实现这种类型的问题,只使用整数和小数,在你的XAML文件,添加一个PreviewTextInput属性到你的textbox,然后在你的XAML .cs文件使用:
private void Text_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
e.Handled = !char.IsDigit(e.Text.Last()) && !e.Text.Last() == '.';
}
每次都检查整个字符串有点多余,除非像其他人提到的那样,你正在使用科学符号(尽管,如果你添加某些字符,如'e',一个添加符号/字符的简单正则表达式非常简单,并在其他答案中说明)。但是对于简单的浮点值,这个解决方案就足够了。
编写为带有lambda表达式的一行代码:
private void Text_PreviewTextInput(object sender, TextCompositionEventArgs e) => e.Handled = !char.IsDigit(e.Text.Last() && !e.Text.Last() == '.');
其他回答
在检查正则表达式之前,我修改了Rays answer以处理突出显示的文本。我还将正则表达式调整为只允许小数点后两位(货币)。
private static readonly Regex _regex = new Regex(@"^[0-9]\d*(\.\d{0,2})?$");
private static bool IsTextAllowed(string text)
{
return _regex.IsMatch(text);
}
private bool IsAllowed(TextBox tb, string text)
{
bool isAllowed = true;
if (tb != null)
{
string currentText = tb.Text;
if (!string.IsNullOrEmpty(tb.SelectedText))
currentText = currentText.Remove(tb.CaretIndex, tb.SelectedText.Length);
isAllowed = IsTextAllowed(currentText.Insert(tb.CaretIndex, text));
}
return isAllowed;
}
private void Txt_PreviewCurrencyTextInput(object sender, TextCompositionEventArgs e)
{
e.Handled = !IsAllowed(sender as TextBox, e.Text);
}
private void TextBoxPasting(object sender, DataObjectPastingEventArgs e)
{
if (e.DataObject.GetDataPresent(typeof(String)))
{
String text = (String)e.DataObject.GetData(typeof(String));
if (!IsAllowed(sender as TextBox, text))
e.CancelCommand();
}
else
e.CancelCommand();
}
还有xaml
<TextBox Name="Txt_Textbox" PreviewTextInput="Txt_PreviewCurrencyTextInput" DataObject.Pasting="TextBoxPasting" />
受雷的启发,我有一个简单的解决方案。这应该足以识别任何形式的数字。
如果您只想要正数、整数值或精确到小数点后最大位数的值,则可以轻松修改此解决方案。
正如Ray的回答所建议的,你需要首先添加一个PreviewTextInput事件:
<TextBox PreviewTextInput="TextBox_OnPreviewTextInput"/>
然后把下面的代码放在后面:
private void TextBox_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
var textBox = sender as TextBox;
// Use SelectionStart property to find the caret position.
// Insert the previewed text into the existing text in the textbox.
var fullText = textBox.Text.Insert(textBox.SelectionStart, e.Text);
double val;
// If parsing is successful, set Handled to false
e.Handled = !double.TryParse(fullText, out val);
}
对于无效的空格,我们可以添加NumberStyles:
using System.Globalization;
private void TextBox_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
var textBox = sender as TextBox;
// Use SelectionStart property to find the caret position.
// Insert the previewed text into the existing text in the textbox.
var fullText = textBox.Text.Insert(textBox.SelectionStart, e.Text);
double val;
// If parsing is successful, set Handled to false
e.Handled = !double.TryParse(fullText,
NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign,
CultureInfo.InvariantCulture,
out val);
}
在Windows窗体中,这很容易;你可以添加一个事件按键和一切工作轻松。然而,在WPF中该事件不存在。但是有一个更简单的方法。
WPF文本框有TextChanged事件,这是一般的一切。它包括粘贴,输入和任何你能想到的东西。
所以你可以这样做:
XAML:
<TextBox name="txtBox1" ... TextChanged="TextBox_TextChanged"/>
背后的代码:
private void TextBox_TextChanged(object sender, TextChangedEventArgs e) {
string s = Regex.Replace(((TextBox)sender).Text, @"[^\d.]", "");
((TextBox)sender).Text = s;
}
这也是可以接受的。,如果你不想要它,只需将它从正则表达式语句中删除为@[^\d]。
注意:此事件可以用于许多TextBox元素,因为它使用发送方对象的文本。您只需编写一次事件,并且可以将其用于多个TextBox元素。
这个怎么样?很适合我。希望我没有漏掉任何边缘情况……
MyTextBox.PreviewTextInput += (sender, args) =>
{
if (!int.TryParse(args.Text, out _))
{
args.Handled = true;
}
};
DataObject.AddPastingHandler(MyTextBox, (sender, args) =>
{
var isUnicodeText = args.SourceDataObject.GetDataPresent(DataFormats.UnicodeText, true);
if (!isUnicodeText)
{
args.CancelCommand();
}
var data = args.SourceDataObject.GetData(DataFormats.UnicodeText) as string;
if (!int.TryParse(data, out _))
{
args.CancelCommand();
}
});
最好和最优雅的解决方案,只允许整数在文本框(甚至在某些范围)是:
XAML:
<TextBox PreviewTextInput="ValidationTextBox" TextChanged="TextBox_TextChanged"/>
C#:
private void ValidationTextBox(object sender, TextCompositionEventArgs e)
{
int max = 100;
//do not allow futher incorrect typing
e.Handled = !(int.TryParse(((TextBox)sender).Text + e.Text, out int i) && i >= 1 && i <= max);
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
int max = 100;
if (!int.TryParse(((TextBox)sender).Text, out int j) || j < 1 || j > max)
{
//delete incoret input
((TextBox)sender).Text = "";
}
else
{
//delete leading zeros
((TextBox)sender).Text = j.ToString();
}
}
你可以调整最小和最大可接受的数字与max (min)通过开关((TextBox)sender). name。
此解决方案不允许输入的前导零或复制粘贴。在每个场景中,文本框中都有一个正确的数字。