我希望接受数字和小数点,但没有符号。
我查看了使用 Windows 窗体 NumericUpDown 控件的示例,以及 此示例来自 Microsoft 的 NumericUpDown 自定义控件。 但到目前为止,NumericUpDown(是否受 WPF 支持)似乎无法提供我想要的功能。 按照我的应用程序的设计方式,任何头脑正常的人都不会想要弄乱箭头。 在我的应用程序中,它们没有任何实际意义。
因此,我正在寻找一种简单的方法来使标准 WPF TextBox 仅接受我想要的字符。 这可能吗? 实用吗?
I'm looking to accept digits and the decimal point, but no sign.
I've looked at samples using the NumericUpDown control for Windows Forms, and this sample of a NumericUpDown custom control from Microsoft. But so far it seems like NumericUpDown (supported by WPF or not) is not going to provide the functionality that I want. The way my application is designed, nobody in their right mind is going to want to mess with the arrows. They don't make any practical sense, in the context of my application.
So I'm looking for a simple way to make a standard WPF TextBox accept only the characters that I want. Is this possible? Is it practical?
发布评论
评论(30)
添加预览文本输入事件。 就像这样:
。如果不允许文本,则在其中设置
e.Handled
。e.Handled = !IsTextAllowed(e.Text);
我在
IsTextAllowed
方法中使用一个简单的正则表达式来查看是否应该允许他们输入的内容。 就我而言,我只想允许数字、点和破折号。如果您想防止粘贴不正确的数据,请连接
DataObject.Pasting
事件DataObject.Pasting="TextBoxPasting"
,如下所示 此处(代码摘录):Add a preview text input event. Like so:
<TextBox PreviewTextInput="PreviewTextInput" />
.Then inside that set the
e.Handled
if the text isn't allowed.e.Handled = !IsTextAllowed(e.Text);
I use a simple regex in
IsTextAllowed
method to see if I should allow what they've typed. In my case I only want to allow numbers, dots and dashes.If you want to prevent pasting of incorrect data hook up the
DataObject.Pasting
eventDataObject.Pasting="TextBoxPasting"
as shown here (code excerpted):事件处理程序正在预览文本输入。 这里,正则表达式仅在文本输入不是数字时才匹配它,并且不会将其写入输入文本框。
如果您只需要字母,请将正则表达式替换为
[^a-zA-Z]
。XAML
XAML.CS 文件
The event handler is previewing text input. Here a regular expression matches the text input only if it is not a number, and then it is not made to entry textbox.
If you want only letters then replace the regular expression as
[^a-zA-Z]
.XAML
XAML.CS FILE
我使用了这里已经存在的一些内容,并使用一种行为对其进行了自己的修改,因此我不必在大量视图中传播此代码...
这是相关的视图代码:
I used some of what was already here and put my own twist on it using a behavior so I don't have to propagate this code throughout a ton of Views...
Here is the relevant view code:
这是 WilP 答案的改进解决方案。
我的改进是:
EmptyValue
属性(如果空字符串不合适)用法非常简单:
This is an improved solution of WilPs answer.
My improvements are:
EmptyValue
property, if empty string is inappropriateUsage is pretty straightforward:
这是使用 MVVM 执行此操作的一种非常简单且容易的方法。
将文本框与视图模型中的整数属性绑定,这将像 gem 一样工作......当在文本框中输入非整数时,它甚至会显示验证。
XAML代码:
查看模型代码:
Here is a very simple and easy way to do this using MVVM.
Bind your textBox with an integer property in the view model, and this will work like a gem ... it will even show validation when a non-integer is entered in the textbox.
XAML code:
View model code:
这里我有一个简单的解决方案,灵感来自 雷的回答。 这应该足以识别任何形式的数字。
如果您只需要正数、整数值或精确到最大小数位数的值等,也可以轻松修改此解决方案。
如 Ray的回答,需要先添加一个
PreviewTextInput
event:然后在后面的代码中添加以下内容:
对于无效的空格,我们可以添加
NumberStyles
:Here I have a simple solution inspired by Ray's answer. This should be sufficient to identify any form of number.
This solution can also be easily modified if you want only positive numbers, integer values or values accurate to a maximum number of decimal places, etc.
As suggested in Ray's answer, you need to first add a
PreviewTextInput
event:Then put the following in the code behind:
To invalid whitespace, we can add
NumberStyles
:添加验证规则,以便当文本更改时,检查以确定数据是否为数字,如果是,则允许继续处理,如果不是,则提示用户该字段中仅接受数字数据。
详细信息请参阅Windows Presentation Foundation 中的验证
Add in a VALIDATION RULE so that when the text changes, check to determine if the data is numeric, and if it is, allows processing to continue, and if it is not, prompts the user that only numeric data is accepted in that field.
Read more in Validation in Windows Presentation Foundation
扩展 WPF 工具包有一个: NumericUpDown
The Extented WPF Toolkit has one: NumericUpDown
还可以简单地实现验证规则并将其应用于文本框:
规则的实现如下(使用与其他答案中建议的相同的正则表达式):
Could also simply implement a validation rule and apply it to the TextBox:
With the implementation of the rule as follow (using the same Regex as proposed in other answers):
另一种方法是使用附加行为,我实现了自定义 TextBoxHelper 类,它可以在我的项目中的所有文本框上使用。 因为我认为为此目的订阅每个文本框和每个单独的 XAML 文件中的事件可能非常耗时。
我实现的 TextBoxHelper 类具有以下功能:
以下是 TextBoxHelper 类的实现:
以下是其简单用法的一些示例:
或者
注意 我的 TextBoxHelper 驻留在 viewHelpers xmlns 别名中。
我希望这个实现可以减轻其他人的工作:)
Another approach will be using an attached behavior, I implemented my custom TextBoxHelper class, which can be used on textboxes all over my project. Because I figured that subscribing to the events for every textboxes and in every individual XAML file for this purpose can be time consuming.
The TextBoxHelper class I implemented has these features:
Here is the implementation of TextBoxHelper class:
And here is some example of its easy usage:
Or
Note that my TextBoxHelper resides in the viewHelpers xmlns alias.
I hope that this implementation eases someone else's work :)
我允许数字键盘数字和退格键:
I allowed numeric keypad numbers and backspace:
这是唯一需要的代码:
这只允许在文本框中输入数字。
要允许使用小数点或减号,您可以将正则表达式更改为
[^0-9.-]+
。This is the only code needed:
This only allows numbers to be inputted into the text box.
To allow a decimal point or minus sign, you can change the regular expression to
[^0-9.-]+
.我将假设:
您希望允许数字输入的文本框仅将其 Text 属性初始设置为某个有效的数字值(例如 2.7172)。
您的文本框是主窗口的子窗口
您的主窗口属于 Window1 类
您的TextBox 名称为 numericTB
基本思想:
添加:
private string previousText;
到您的主窗口类 (Window1)添加:
previousText = numericTB.Text;
到您的主窗口构造函数为 numericTB.TextChanged 事件创建一个处理程序,如下所示:
只要它有效,这将继续将 previousText 设置为 numericTB.Text,并在以下情况下将 numericTB.Text 设置为其最后一个有效值:用户写了一些你不喜欢的东西。 当然,这只是基本思想,只是“抗白痴”,而不是“防白痴”。 例如,它不处理用户弄乱空格的情况。 因此,这是一个完整的解决方案,我认为这是“白痴证明”,如果我错了,请告诉我:
您的 Window1.xaml 文件的内容:
Window.xaml.cs 文件的内容:
就是这样。 如果您有许多 TextBox,那么我建议创建一个继承自 TextBox 的 CustomControl,以便您可以将 previousText 和 numericTB_TextChanged 包装在单独的文件中。
I will assume that:
Your TextBox for which you want to allow numeric input only has its Text property initially set to some valid number value (for example, 2.7172).
Your Textbox is a child of your main window
Your main window is of class Window1
Your TextBox name is numericTB
Basic idea:
Add:
private string previousText;
to your main window class (Window1)Add:
previousText = numericTB.Text;
to your main window constructorCreate a handler for the numericTB.TextChanged event to be something like this:
This will keep setting previousText to numericTB.Text as long as it is valid, and set numericTB.Text to its last valid value if the user writes something that you don't like. Of course, this is just basic idea, and it is just "idiot resistant", not "idiot proof". It doesn't handle the case in which the user messes with spaces, for example. So here is a complete solution which I think is "idiot proof", and if I'm wrong please tell me:
Content of your Window1.xaml file:
Content of your Window.xaml.cs file:
And that's it. If you have many TextBoxes then I recommend creating a CustomControl that inherits from TextBox, so you can wrap previousText and numericTB_TextChanged up in a separate file.
如果您不想编写大量代码来执行基本功能(我不知道为什么人们会编写很长的方法),您可以这样做:
添加命名空间:
在 XAML 中,设置 TextChanged 属性:
在 WPF 中的 txt1_TextChanged 方法下,添加
Regex.Replace
:If you do not want to write a lot of code to do a basic function (I don't know why people make long methods) you can just do this:
Add namespace:
In XAML, set a TextChanged property:
In WPF under txt1_TextChanged method, add
Regex.Replace
:在 Windows 窗体中这很容易; 您可以为按键添加一个事件,一切都会轻松进行。 然而,在 WPF 中,该事件不存在。 但有一种更简单的方法。
WPF TextBox 具有适用于所有内容的通用 TextChanged 事件。 它包括粘贴、打字以及任何你能想到的事情。
所以你可以这样做:
XAML:
CODE BEHIND:
这也接受
.
,如果你不想要它,只需将其删除将regex
语句改为@[^\d]
。注意:此事件可用于许多 TextBox 元素,因为它使用
sender
对象的 Text。 您只需编写该事件一次,即可将其用于多个 TextBox 元素。In Windows Forms it was easy; you can add an event for KeyPress and everything works easily. However, in WPF that event isn't there. But there is a much easier way for it.
The WPF TextBox has the TextChanged event which is general for everything. It includes pasting, typing and whatever that can come up to your mind.
So you can do something like this:
XAML:
CODE BEHIND:
This also accepts
.
, if you don't want it, just remove it from theregex
statement to be@[^\d]
.Note: This event can be used on many TextBox elements as it uses the
sender
object's Text. You only write the event once and can use it for multiple TextBox elements.对于那些寻求仅使用整数和小数来快速且非常简单地实现此类问题的人,请在 XAML 文件中向
TextBox
添加一个PreviewTextInput
属性,然后在您的 xaml.cs 文件使用:每次都检查整个字符串有点多余,除非,正如其他人提到的,您正在使用科学记数法做一些事情(尽管,如果您添加某些字符,例如“e”,a添加符号/字符的简单正则表达式非常简单,并在其他答案中进行了说明)。 但对于简单的浮点值,这个解决方案就足够了。
写成带有 lambda 表达式的单行代码:
For those looking for a quick and very simple implementation for this type of problem using only integers and decimal, in your XAML file, add a
PreviewTextInput
property to yourTextBox
and then in your xaml.cs file use:It's kind of redundant to keep checking the entire string every time unless, as others have mentioned, you're doing something with scientific notation (albeit, if you're adding certain characters like 'e', a simple regex adding symbols/characters is really simple and illustrated in other answers). But for simple floating point values, this solution will suffice.
Written as a one-liner with a lambda expression:
对于希望其文本字段仅接受无符号数字(例如套接字端口等)的开发人员:
WPF
C#
For developers who want their text fields to accept unsigned numbers only such as socket ports and so on:
WPF
C#
只允许文本框中的整数(即使在某些范围内)的最佳和最优雅的解决方案是:
XAML:
C#:
您可以通过打开
((TextBox)sender 来调整 max (min) 的最小和最大可接受数字).名称
。此解决方案不允许前导零或复制粘贴输入。 在每种情况下,文本框中都会有正确的数字。
The best and most elegant solution to only allow integer numbers in textbox (even in some range) is:
XAML:
C#:
You can adjust the minimal and maximal acceptable number with max (min) by switch on
((TextBox)sender).Name
.This solution does not allow leading zeros or copy pasting the input. In every scenario you will have a correct number in the textbox.
在文本框的预览 keydown 事件中。
in preview keydown event of textbox.
我们可以对文本框更改事件进行验证。 以下实现阻止除数字和一位小数点之外的按键输入。
We can do validation on text box changed event. The following implementation prevents keypress input other than numeric and one decimal point.
这个怎么样? 对我来说效果很好。 希望我没有错过任何边缘情况......
How about this? Works well for me. Hope I didn't miss any edge cases...
现在我知道这个问题有一个可接受的答案,但就我个人而言,我发现它有点令人困惑,我相信它应该更容易比起那个来说。 因此,我将尝试演示如何让它尽可能地工作:
在 Windows 窗体 中,有一个名为
KeyPress
的事件,它非常适合这种情况任务。 但 WPF 中不存在这种情况,因此我们将使用PreviewTextInput
事件。 另外,对于验证,我相信可以使用foreach
循环遍历textbox.Text
并检查它是否匹配;)条件,但老实说,这就是 正则表达式 的用途。在我们深入探讨神圣代码之前,还有一件事。 对于要触发的事件,可以做两件事:
Loaded
中执行此操作code> 表单的事件(文本框位于其中):textBox.PreviewTextInput += onlyNumeric;
我认为第二种方法更好,因为在这种情况下,您通常需要将相同的条件(
regex
)应用于更多比一个TextBox
和你不想重复自己!。最后,您可以这样做:
Now I know this question has an accepted answer, but personally, I find it a bit confusing and I believe it should be easier than that. So I'll try to demonstrate how I got it to work as best as I can:
In Windows Forms, there's an event called
KeyPress
which is perfectly good for this kind of task. But that doesn't exist in WPF, so instead, we'll be using thePreviewTextInput
event. Also, for the validation, I believe one can use aforeach
to loop through thetextbox.Text
and check if it matches ;) the condition, but honestly, this is what regular expressions are for.One more thing before we dive into the holy code. For the event to be fired, one can do two things:
<PreviewTextInput="textBox_PreviewTextInput/>
Loaded
event of the form (which the textBox is in):textBox.PreviewTextInput += onlyNumeric;
I think the second method is better because in situations like this, you'll mostly be required to apply the same condition (
regex
) to more than oneTextBox
and you don't want to repeat yourself!.Finally, here's how you'd do it:
这是我的版本。 它基于 ValidatingTextBox 基类,如果不“有效”,该类只会撤消已完成的操作。 它支持粘贴、剪切、删除、退格、+、-等。
对于32位整数,有一个Int32TextBox类,它只与int进行比较。 我还添加了浮点验证类。
注意1:使用WPF绑定时,必须确保使用适合绑定属性类型的类,否则可能会导致奇怪的结果。
注意 2:将浮点类与 WPF 绑定一起使用时,请确保绑定使用当前区域性来匹配我使用的 TryParse 方法。
Here is my version of it. It's based on a base
ValidatingTextBox
class that just undoes what has been done if it's not "valid". It supports paste, cut, delete, backspace, +, - etc.For 32-bit integer, there is a Int32TextBox class that just compares with an int. I have also added floating point validation classes.
Note 1: When using WPF binding, you must make sure you use the class that fits the bound property type otherwise, it may lead to strange results.
Note 2: When using floating point classes with WPF binding, make sure the binding uses the current culture to match the TryParse method I've used.
我修改了 Rays answer 以在检查正则表达式之前处理突出显示的文本。 我还调整了正则表达式,只允许两位小数(货币)。
还有xaml
I modified Rays answer to handle the highlighted text prior to checking the regular expression. I also adjusted the regular expression to only allow for two decimal places (currency).
And the xaml
这是一个用于 WPF 中数字输入的库
它具有诸如
NumberStyles 和
RegexPattern
用于验证。WPF 子类
TextBox
Here is a library for numeric input in WPF
It has properties like
NumberStyles
andRegexPattern
for validation.Subclasses WPF
TextBox
使用:
Use:
我正在为一个简单的项目使用未绑定的盒子,因此我无法使用标准绑定方法。 因此,我创建了一个简单的技巧,其他人可能会发现通过简单地扩展现有的 TextBox 控件非常方便:
显然,对于浮动类型,您可能希望将其解析为浮点数等。 同样的原则也适用。
然后在XAML文件中您需要包含相关的命名空间:
之后您可以将其用作常规控件:
I was working with an unbound box for a simple project I was working on, so I couldn't use the standard binding approach. Consequently I created a simple hack that others might find quite handy by simply extending the existing TextBox control:
Obviously, for a floating type, you would want to parse it as a float and so on. The same principles apply.
Then in the XAML file you need to include the relevant namespace:
After that you can use it as a regular control:
这就是我用来获取接受数字和小数点的 WPF 文本框的方法:
将代码放入新的类文件中,
在文件顶部添加并构建解决方案。 numericTextBox 控件随后将出现在工具箱的顶部。
This is what I would use to get a WPF textbox that accept digits and the decimal point:
Put the code in a new class file, add
at the top of the file and build the solution. The numericTextBox control will then appear at the top of the toolbox.
使用这里的一些解决方案一段时间后,我开发了自己的解决方案,它非常适合我的 MVVM 设置。 请注意,从某种意义上说,它不像其他一些那样动态,仍然允许用户输入错误的字符,但它会阻止他们按下按钮并因此执行任何操作。 这很符合我的主题,即当无法执行操作时按钮会变灰。
我有一个
TextBox
,用户必须输入要打印的多个文档页面:...使用此绑定属性:
我还有一个按钮:
...使用此命令绑定:
然后是
SetNumberOfPages()
方法,但对于本主题来说并不重要。 它在我的情况下效果很好,因为我不必将任何代码添加到视图的代码隐藏文件中,并且它允许我使用Command
属性控制行为。After using some of the solutions here for some time, I developed my own that works well for my MVVM setup. Note that it's not as dynamic as some of the other ones in a sense of still allowing users to enter erroneous characters, but it blocks them from pressing the button and thus doing anything. This goes well with my theme of graying out buttons when actions cannot be performed.
I have a
TextBox
that a user must enter a number of document pages to be printed:...with this binding property:
I also have a button:
...with this command binding:
And then there's the method of
SetNumberOfPages()
, but it's unimportant for this topic. It works well in my case because I don't have to add any code into the View's code-behind file and it allows me to control behavior using theCommand
property.