C# textBox 十六进制仅具有 0x/h/$ 前缀,使用 TextChanged 属性

本文关键字:前缀 使用 属性 TextChanged 十六进制 0x textBox | 更新日期: 2023-09-27 18:31:19

我正在 TextChanged 属性中测试以下代码以仅允许文本框中的十六进制值,并且它工作正常,它还删除与 HEX 模式不匹配的粘贴字符串并将小写转换为大写,这正是我所需要的:

Regex nonhex = new Regex("[^0-9,a-f,A-F]");
int caret = textBox1.SelectionStart - textBox1.Text.Length;
textBox1.Text = nonhex.Replace(textBox1.Text, "").ToUpper();
textBox1.SelectionStart = caret + textBox1.Text.Length;

如果我尝试添加前缀,上面的代码只会删除它。修改代码以允许添加永久前缀(如 0x、h、$)以便我只使用正则表达式和 TextChnaged 属性的最佳方法是什么,无论如何可能吗?我还需要能够指定十六进制值的最大长度,例如 PID 和 VID HID 设备的 4 位数字,因为我可能会在一些需要或多或少十六进制数字的不同项目中使用它。

我在论坛中寻找类似的解决方案,但大多数人使用多个事件,几乎无法实现这四行可以做的事情。 顺便说一句,使用正则表达式不是边界犯罪。

谢谢

C# textBox 十六进制仅具有 0x/h/$ 前缀,使用 TextChanged 属性

你用这四行做的是你把验证和更正结合起来,这充其量是困难的,在许多情况下是不可能的。如果确实要执行此操作,则首先必须验证输入。仅当它无效时,才应对其进行修改。

我建议您创建一个首先验证的正则表达式,如下所示:

Regex validInput = new Regex(@"^('$|h|0x)?[0-9a-f]*", RegexOptions.IgnoreCase);
if (validInput.IsMatch(textBox1.Text))
{
    return;
}

如果你过了那个点,那么你就知道文本在某种程度上是坏的。如果你想纠正它,你必须确定它在哪里不好。而且你不会用一个正则表达式来做到这一点。您必须确定是否存在有效的前缀。如果有有效的前缀,则可以检查文本的其余部分以查看它是否是有效的十六进制数。如果没有有效的前缀,则检查整个字段以查看它是否为有效数字。

确定错误所在后,您必须修复它。即使在您描述的简单情况下,这也很困难。

我认为你这样做的方式完全错误。

基本上有三种方法可以处理验证:

  1. 让用户输入他想要的任何文本。你把它标记为坏,但你保持原样,让用户改变它。
  2. 防止用户输入不允许的字符。例如,只让他在数字输入字段中输入数字。
  3. 当用户输入错误数据时自动更正文本。

你选择了#3,这通常是最困难的(正如我上面描述的),在我看来,作为用户,是最烦人的可能选项。

你会遇到各种各样的问题。例如,假设用户输入了"01AB",然后他回到开头并键入"x",给出"x01AB"。但你不喜欢这样。你想要"0x01AB",所以你从字符串中删除"x"。用户认为,"呵呵。我以为我按了'x'。所以他又试了一次。在他发现你的代码如此"有用"地阻止他输入错误数据之前,需要两到三次尝试。作为一个用户,我发现这非常烦人,每当我遇到它时,我都想找到编写它的程序员并将他关起来,这样他就不会再犯下这种丑陋的行为了。

多年来,我发现第一个选项最容易编码,作为用户,最容易使用。如果用户输入了错误数据,您可以轻松验证它并通知用户他犯了错误:通常通过更改输入框周围的边框,在其旁边放置错误指示器,并可能显示一些文本,说明输入错误的原因以及如何更正它。使用我上面的例子:

Regex validInput = new Regex(@"^('$|h|0x)?[0-9a-f]*", RegexOptions.IgnoreCase);
if (validInput.IsMatch(textBox1.Text))
{
    // input is good. Clear errors.
    return;
}
// Input is bad. Show error indicator.

现在,如果用户按下"确定"或"保存"按钮或其他任何按钮,并且仍然存在不良数据,则必须捕获该按钮并采取相应的行动(即不要让程序继续处理错误数据)。但这比尝试更正用户键入的内容要容易得多,而且也不那么烦人。