【问题标题】:Creating a hexadecimal NumericUpDown control创建十六进制 NumericUpDown 控件
【发布时间】:2015-05-28 06:05:58
【问题描述】:

我通过子类化基本 NumericUpDown 并添加以下方法创建了一个十六进制 NumericUpDown 控件:

protected override void UpdateEditText()
{
  this.Text = "0x" + ((int) Value).ToString("X2");
}

这很好用。该控件现在以以下格式显示值:

0x3F

这正是我所追求的。

但有一件事困扰着我:每次分配 Text 属性时,都会抛出 System.FormatException。这似乎并没有影响控件的功能,但我仍然认为它很难看。

这是调用栈的顶部:

MyAssembly.dll!HexNumericUpDown.UpdateEditText() 第 31 行 C# System.Windows.Forms.dll!System.Windows.Forms.NumericUpDown.ValidateEditText() 未知 System.Windows.Forms.dll!System.Windows.Forms.UpDownBase.Text.set(string value) Unknown

我可以忽略这个异常吗?或者有没有一种干净的方法来摆脱这个?

【问题讨论】:

  • 您是否在 TextChanged 事件上运行了某些东西,试图将字符串转换回整数?
  • “每次分配 Text-property 时,都会抛出 System.FormatException”但是在哪里?发布堆栈跟踪。
  • 完成。我已经添加了堆栈跟踪。
  • 文本无效。您应该覆盖 ValidateEditText 并允许使用十六进制字符串

标签: c# .net winforms


【解决方案1】:

您需要重写 ValidateEditText() 方法,以便正确处理(可选)“0x”前缀。并覆盖 UpdateEditText() 以添加前缀“0x”。向您的项目添加一个新类并粘贴如下所示的代码。编译。将工具箱顶部的新控件拖放到表单上:

using System;
using System.Windows.Forms;

class HexUpDown : NumericUpDown {
    public HexUpDown() {
        this.Hexadecimal = true;
    }

    protected override void ValidateEditText() {
        try {
            var txt = this.Text;
            if (!string.IsNullOrEmpty(txt)) {
                if (txt.StartsWith("0x")) txt = txt.Substring(2);
                var value = Convert.ToDecimal(Convert.ToInt32(txt, 16));
                value = Math.Max(value, this.Minimum);
                value = Math.Min(value, this.Maximum);
                this.Value = value;
            }
        }
        catch { }
        base.UserEdit = false;
        UpdateEditText();
    }

    protected override void UpdateEditText() {
        int value = Convert.ToInt32(this.Value);
        this.Text = "0x" + value.ToString("X4");
    }
}

Fwiw,古怪的 try/catch-em-all 直接来自 .NET 版本。我保留它以使控件的行为方式相同。按照你想要的方式调整 ToString() 参数。

【讨论】:

    【解决方案2】:

    我猜你还需要重写 ParseEditText ValidateEditText 方法,以接受十六进制值并将 Value 属性设置为正确的 int 值。

    【讨论】:

    • ParseEditText 不是虚拟的,但 ValidateEditText 是
    【解决方案3】:

    casting 和 ConvertTo 是有区别的:

    (int)obj - 这是 obj 到 int 类型的显式转换,您是在告诉编译器 obj 是一个 int。如果 obj 不是 int 类型,您将得到一个强制转换异常。但它不是真正 int。 X2 格式需要真正的整数。

    Convert.ToInt32(obj) - 这是对 Convert 类的显式调用,以返回 obj 的 int 表示

    因此您需要使用Convert.ToInt32(Value)

    但是在 MSDN 中说:

    1)此 API (numericUpDown.Text) 支持 .NET Framework 基础设施,不打算直接从您的代码中使用。

    2)Text 对 NumericUpDown 的外观没有影响 控制;因此,它隐藏在设计器中并从 智能感知。

    【讨论】:

    • 这并不能解决问题。将值分配给属性 Text 时会发生异常。 int-casting 不会导致异常。
    • this.Text,什么是“this”?
    • 这是 NumericUpDown 控件。
    • 我编辑了答案,因为评论有点长
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-05
    • 2014-04-08
    • 2021-05-09
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多