- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我知道这是一个有很多答案的古老问题,但我还没有找到任何好的、可靠的答案。
要求是一个始终包含 Double.TryParse 将返回 true 的字符串的文本框。
我见过的大多数实现都没有防止输入,例如:“10.45.8”。这是一个问题。
最好的方法是完全使用事件,例如 TextInput 和 KeyDown(用于空格)。这些的问题是获取表示更改前的新文本(或更改后的旧文本)的字符串非常复杂。 TextChanged 的问题是它没有提供获取旧文本的方法。
如果您能以某种方式在更改之前获取新文本,那将是最有帮助的,因为您可以针对 Double.TryParse 对其进行测试。不过可能有更好的解决方案。
执行此操作的最佳方法是什么?
这个问题的最佳答案是采用多种方法并对它们进行比较。
最佳答案
方法一
将 TextChanged
和 KeyDown
事件组合用于 TextBox
。在 KeyDown
上,您可以将当前文本保存在文本框中,然后在 TextChanged
事件中执行您的 Double.TryParse
。如果输入的文本无效,您将恢复为旧文本值。这看起来像:
private int oldIndex = 0;
private string oldText = String.Empty;
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
double val;
if (!Double.TryParse(textBox1.Text, out val))
{
textBox1.TextChanged -= textBox1_TextChanged;
textBox1.Text = oldText;
textBox1.CaretIndex = oldIndex;
textBox1.TextChanged += textBox1_TextChanged;
}
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
oldIndex = textBox1.CaretIndex;
oldText = textBox1.Text;
}
CaratIndex
有助于避免在验证失败时将光标移动到第一个位置而烦死用户。但是,此方法不会捕获 SpaceBar 按键。它将允许输入像这样的文本“1234.56”。此外,粘贴文本将不会得到正确验证。除此之外,我不喜欢在文本更新期间弄乱事件处理程序。
方法二
这种方法应该可以满足您的需求。
使用 PreviewKeyDown
和 PreviewTextInput
事件处理程序。通过观察这些事件并进行相应的处理,您无需担心恢复到文本框中以前的文本值。 PreviewKeyDown
可用于监视和忽略您的 SpaceBar 按键,PreviewTextInput
可用于在分配新文本框值之前对其进行测试。
private void textBox1_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space)
{
e.Handled = true;
}
}
private void textBox1_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
//Create a string combining the text to be entered with what is already there.
//Being careful of new text positioning here, though it isn't truly necessary for validation of number format.
int cursorPos = textBox1.CaretIndex;
string nextText;
if (cursorPos > 0)
{
nextText = textBox1.Text.Substring(0, cursorPos) + e.Text + textBox1.Text.Substring(cursorPos);
}
else
{
nextText = textBox1.Text + e.Text;
}
double testVal;
if (!Double.TryParse(nextText, out testVal))
{
e.Handled = true;
}
}
这种方法可以更好地在无效输入进入文本框之前捕获它。但是,将事件设置为 Handled
我想可能会给您带来麻烦,具体取决于消息路由列表中的其余目的地。此处未处理的最后一部分是用户将无效输入粘贴到文本框中的能力。这可以通过添加此代码来处理,该代码基于 Paste Event in a WPF TextBox 构建.
private void OnPaste(object sender, DataObjectPastingEventArgs e)
{
double testVal;
bool ok = false;
var isText = e.SourceDataObject.GetDataPresent(System.Windows.DataFormats.Text, true);
if (isText)
{
var text = e.SourceDataObject.GetData(DataFormats.Text) as string;
if (Double.TryParse(text, out testVal))
{
ok = true;
}
}
if (!ok)
{
e.CancelCommand();
}
}
在 InitializeComponent
调用之后使用此代码添加此处理程序:
DataObject.AddPastingHandler(textBox1, new DataObjectPastingEventHandler(OnPaste));
关于c# - 数字文本框 - 使用 Double.TryParse,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9131931/
C# 中的 Single.TryParse 和 float.TryParse 有什么区别? float a, b; float.TryParse("0.01", out a); Single.TryP
在 C# 中,为什么 int.TryParse 不能解析数字分组(但 double.TryParse 可以)? int i1 = 13579; string si1 =
我已按值或其名称将代码写到TryParse枚举,如下所示。如何扩展此代码以包含具有Flags属性的枚举? public static bool TryParse(this T enum_typ
我构建了一个玩具电子表格来帮助学习 F#。当我处理新单元格的文本时,我将其存储为可识别类型。为了解析它,我觉得我应该能够做类似的事情: let cv = mat
我有一个枚举(假设是 DemoEnum),我想解析该枚举的值。我正在写 DemoEnum value; if(DemoEnum.TryParse("input", out value)) { t
我构建了一个玩具电子表格来帮助学习 F#。当我处理新单元格的文本时,我将其存储为可识别类型。为了解析它,我觉得我应该能够做类似的事情: let cv = mat
我有以下代码。 using System; class program { static void Main() { string StrNumber = "100TG
这个问题在这里已经有了答案: How to use int.TryParse with nullable int? [duplicate] (5 个答案) 关闭 4 年前。 我想制作一个方法 int
今天我读了一篇文章,其中写道我们应该始终使用 TryParse(string, out MMM) 进行转换而不是 Convert.ToMMM()。 我同意这篇文章,但在那之后我陷入了一种情况。 当字符
我需要验证某些变量是否可以创建有效的日期时间,如果可以,则在不抛出异常的情况下忽略它。 我有以下代码 int y, m, d, h, mi, s, tz; ogrFeature.GetFieldAs
我正在尝试运行 NUnit 测试来搜索字符串中的数字。我正在使用 TryParse,但它给了我一个错误:Error1:'int.TryParse(string, out int)' 的最佳重载方法匹配
我需要检查一个对象是否可以转换为特定的数据类型,并想出了这个: public static bool TryParseAll(System.Type typeToConvert, object val
Facebook API 函数 FacebookOAuthResult.TryParse() 未解析。我为 TryParse 函数提供了正确的输入参数。我已经在该项目的 Visual Studio 引
我是编程新手,我正在尝试创建一个循环,其中 while 条件基于变量,但我不知道它的正确语法。这就是我想要做的,即使它可能不被允许......我认为。 using System; using Syst
我知道它不会抛出异常,因此它可能会明显更快,而且,您很可能使用它来将输入转换为您可以使用的数据,所以我认为它没有被这样使用通常会在性能方面产生如此大的差异。 无论如何,我看到的例子都是 if/else
我想尝试将 string 解析为 DateTime?,如果失败,则将值设置为 null。我能想到的唯一方法如下,但它看起来不是很整洁。 DateTime temp; DateTime? whatIAc
在我的应用程序中,我有一个文本框 - txtDiscount,管理员可以在其中为某个用户设置折扣百分比,也可以不设置。在后端我想保存数据所以现在我有这个: double? discount = nul
我尝试按如下方式解析来自外部系统的日期时间戳: DateTime expiration; DateTime.TryParse("2011-04-28T14:00:00", out expiration
我在让 TryParse 为我正常工作时遇到问题。我有一个值列表,我几乎可以肯定这些值是有效的(因为它们来 self 们系统中的另一个组件),但我想确保有适当的错误处理。 这是我的值(value)观的
我想覆盖 bool 的 TryParse 方法来接受"is"和“否”。我知道我想使用的方法(如下),但我不知道如何覆盖 bool 的方法。 ... bool TryParse(string value
我是一名优秀的程序员,十分优秀!