我希望接受数字和小数点,但没有符号。
我已经看过使用Windows窗体中的NumericUpDown控件的示例,以及来自微软的这个NumericUpDown自定义控件的示例。但到目前为止,似乎NumericUpDown (WPF是否支持)不会提供我想要的功能。我的应用程序是这样设计的,任何头脑正常的人都不会想弄乱箭头。在我的应用程序中,它们没有任何实际意义。
所以我正在寻找一个简单的方法,使一个标准的WPF文本框只接受我想要的字符。这可能吗?实用吗?
我希望接受数字和小数点,但没有符号。
我已经看过使用Windows窗体中的NumericUpDown控件的示例,以及来自微软的这个NumericUpDown自定义控件的示例。但到目前为止,似乎NumericUpDown (WPF是否支持)不会提供我想要的功能。我的应用程序是这样设计的,任何头脑正常的人都不会想弄乱箭头。在我的应用程序中,它们没有任何实际意义。
所以我正在寻找一个简单的方法,使一个标准的WPF文本框只接受我想要的字符。这可能吗?实用吗?
当前回答
我假设:
您希望允许数字输入的文本框的文本属性最初设置为一些有效的数字值(例如,2.7172)。 文本框是主窗口的子窗口 你的主窗口是Window1类 您的文本框名称是numericTB
基本思想:
Add: private string previousText; to your main window class (Window1) Add: previousText = numericTB.Text; to your main window constructor Create a handler for the numericTB.TextChanged event to be something like this: private void numericTB_TextChanged(object sender, TextChangedEventArgs e) { double num = 0; bool success = double.TryParse(((TextBox)sender).Text, out num); if (success & num >= 0) previousText = ((TextBox)sender).Text; else ((TextBox)sender).Text = previousText; }
这将继续设置previousText为numericTB。文本只要它是有效的,并设置numericTB。如果用户写了您不喜欢的内容,则将文本转换到其最后一个有效值。当然,这只是基本的想法,它只是“傻瓜抵抗”,而不是“傻瓜证明”。例如,它不能处理用户乱用空格的情况。所以这里有一个完整的解决方案,我认为是“白痴证明”,如果我错了,请告诉我:
Content of your Window1.xaml file: <Window x:Class="IdiotProofNumericTextBox.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Grid> <TextBox Height="30" Width="100" Name="numericTB" TextChanged="numericTB_TextChanged"/> </Grid> </Window> Content of your Window.xaml.cs file: 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; namespace IdiotProofNumericTextBox { public partial class Window1 : Window { private string previousText; public Window1() { InitializeComponent(); previousText = numericTB.Text; } private void numericTB_TextChanged(object sender, TextChangedEventArgs e) { if (string.IsNullOrEmpty(((TextBox)sender).Text)) previousText = ""; else { double num = 0; bool success = double.TryParse(((TextBox)sender).Text, out num); if (success & num >= 0) { ((TextBox)sender).Text.Trim(); previousText = ((TextBox)sender).Text; } else { ((TextBox)sender).Text = previousText; ((TextBox)sender).SelectionStart = ((TextBox)sender).Text.Length; } } } } }
就是这样。如果你有很多文本框,那么我建议创建一个CustomControl继承从TextBox,所以你可以包装previousText和numericTB_TextChanged在一个单独的文件。
其他回答
在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元素。
在使用这里的一些解决方案一段时间后,我开发了自己的解决方案,该解决方案适用于我的MVVM设置。注意,在允许用户输入错误字符的意义上,它不像其他一些那样动态,但它阻止用户按下按钮,从而阻止他们做任何事情。这很好地配合了我的主题,即当操作无法执行时将按钮变灰。
我有一个文本框,用户必须输入一些文档页面要打印:
<TextBox Text="{Binding NumberPagesToPrint, UpdateSourceTrigger=PropertyChanged}"/>
...使用这个绑定属性:
private string _numberPagesToPrint;
public string NumberPagesToPrint
{
get { return _numberPagesToPrint; }
set
{
if (_numberPagesToPrint == value)
{
return;
}
_numberPagesToPrint = value;
OnPropertyChanged("NumberPagesToPrint");
}
}
我还有一个按钮:
<Button Template="{DynamicResource CustomButton_Flat}" Content="Set"
Command="{Binding SetNumberPagesCommand}"/>
...使用此命令绑定:
private RelayCommand _setNumberPagesCommand;
public ICommand SetNumberPagesCommand
{
get
{
if (_setNumberPagesCommand == null)
{
int num;
_setNumberPagesCommand = new RelayCommand(param => SetNumberOfPages(),
() => Int32.TryParse(NumberPagesToPrint, out num));
}
return _setNumberPagesCommand;
}
}
然后是SetNumberOfPages()方法,但对于本主题不重要。它在我的案例中工作得很好,因为我不需要向视图的代码隐藏文件中添加任何代码,并且它允许我使用Command属性控制行为。
添加预览文本输入事件。像这样:<TextBox PreviewTextInput="PreviewTextInput" />。
然后在这个set中,如果文本不被允许,e。handled。e.Handled = ! istextallows (e.Text);
我在istextalered方法中使用一个简单的正则表达式来查看我是否应该允许他们键入的内容。在我的例子中,我只允许数字、点和破折号。
private static readonly Regex _regex = new Regex("[^0-9.-]+"); //regex that matches disallowed text
private static bool IsTextAllowed(string text)
{
return !_regex.IsMatch(text);
}
如果您希望防止粘贴不正确的数据,请连接数据对象。粘贴事件数据对象。粘贴="TextBoxPasting"如下所示(代码摘录):
// Use the DataObject.Pasting Handler
private void TextBoxPasting(object sender, DataObjectPastingEventArgs e)
{
if (e.DataObject.GetDataPresent(typeof(String)))
{
String text = (String)e.DataObject.GetData(typeof(String));
if (!IsTextAllowed(text))
{
e.CancelCommand();
}
}
else
{
e.CancelCommand();
}
}
Use:
Private Sub DetailTextBox_PreviewTextInput( _
ByVal sender As Object, _
ByVal e As System.Windows.Input.TextCompositionEventArgs) _
Handles DetailTextBox.PreviewTextInput
If _IsANumber Then
If Not Char.IsNumber(e.Text) Then
e.Handled = True
End If
End If
End Sub
这是我用来获得一个接受数字和小数点的WPF文本框:
class numericTextBox : TextBox
{
protected override void OnKeyDown(KeyEventArgs e)
{
bool b = false;
switch (e.Key)
{
case Key.Back: b = true; break;
case Key.D0: b = true; break;
case Key.D1: b = true; break;
case Key.D2: b = true; break;
case Key.D3: b = true; break;
case Key.D4: b = true; break;
case Key.D5: b = true; break;
case Key.D6: b = true; break;
case Key.D7: b = true; break;
case Key.D8: b = true; break;
case Key.D9: b = true; break;
case Key.OemPeriod: b = true; break;
}
if (b == false)
{
e.Handled = true;
}
base.OnKeyDown(e);
}
}
将代码放在一个新的类文件中,添加
using System.Windows.Controls;
using System.Windows.Input;
并构建解决方案。numericTextBox控件将出现在工具箱的顶部。