在数字后面有NumericUpDown控件内的文本

时间:2011-05-07 13:45:55

标签: c# .net winforms string numericupdown

在WinForms中是否可以在NumericUpDown控件中显示文本?例如,我想显示我的numericupdown控件中的值是微安培,所以它应该像“1 uA”。

感谢。

4 个答案:

答案 0 :(得分:27)

标准控件中没有内置此类功能。但是,通过创建一个继承自NumericUpDown类的自定义控件并覆盖UpdateEditText method来相应地格式化数字,可以相当容易地添加它。

例如,您可能具有以下类定义:

public class NumericUpDownEx : NumericUpDown
{
    public NumericUpDownEx()
    {
    }

    protected override void UpdateEditText()
    {
        // Append the units to the end of the numeric value
        this.Text = this.Value + " uA";
    }
}

或者,要获得更完整的实施,请参阅此示例项目:NumericUpDown with unit measure

答案 1 :(得分:1)

我最近偶然发现了这个问题,并找到了Cody Gray的精彩答案。我使用它对我有利,但最近引起了他的回答的一个评论,他们谈到如果后缀仍然存在,文本将如何验证失败。我已经为此创建了一个可能不那么专业的快速解决方案。

基本上,数字会读取this.Text字段。

找到数字后,它们会被放入ParseEditText();,但需要进行辩论或任何您想要调用的数据,以确保我们不会创建堆栈溢出

只有包含号码的新文字输入后,系统会调用普通UpdateEditText();public class NumericUpDownUnit : System.Windows.Forms.NumericUpDown { public string Suffix{ get; set; } private bool Debounce = false; public NumericUpDownUnit() { } protected override void ValidateEditText() { if (!Debounce) //I had to use a debouncer because any time you update the 'this.Text' field it calls this method. { Debounce = true; //Make sure we don't create a stack overflow. string tempText = this.Text; //Get the text that was put into the box. string numbers = ""; //For holding the numbers we find. foreach (char item in tempText) //Implement whatever check wizardry you like here using 'tempText' string. { if (Char.IsDigit(item)) { numbers += item; } else { break; } } decimal actualNum = Decimal.Parse(numbers, System.Globalization.NumberStyles.AllowLeadingSign); if (actualNum > this.Maximum) //Make sure our number is within min/max this.Value = this.Maximum; else if (actualNum < this.Minimum) this.Value = this.Minimum; else this.Value = actualNum; ParseEditText(); //Carry on with the normal checks. UpdateEditText(); Debounce = false; } } protected override void UpdateEditText() { // Append the units to the end of the numeric value this.Text = this.Value + Suffix; } } 来完成此过程。

这不是最资源友好或最有效的解决方案,但今天大多数现代计算机应该完全没问题。

此外,您还会注意到我已经创建了一个用于更改后缀的属性,以便在编辑器中使用。

{{1}}

如果出现问题,请随意改善我的回答或纠正我,我是一名自学成才的程序员,仍在学习。

答案 2 :(得分:1)

使用CodeGray's答案,对Fabio's的注释使ValidateEditText失败,以及NumericUpDown documentation我提出了一个简单的NumericUpDownWithUnit组件。您可以按原样复制/粘贴:

using System;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Windows.Forms;

public class NumericUpDownWithUnit : NumericUpDown
{
    #region| Fields |

    private string unit = null;
    private bool unitFirst = true;

    #endregion

    #region| Properties |

    public string Unit
    {
        get => unit;
        set
        {
            unit = value;

            UpdateEditText();
        }
    }

    public bool UnitFirst
    {
        get => unitFirst;
        set
        {
            unitFirst = value;

            UpdateEditText();
        }
    }

    #endregion

    #region| Methods |

    /// <summary>
    /// Method called when updating the numeric updown text.
    /// </summary>
    protected override void UpdateEditText()
    {
        // If there is a unit we handle it ourselfs, if there is not we leave it to the base class.
        if (Unit != null && Unit != string.Empty)
        {
            if (UnitFirst)
            {
                Text = $"({Unit}) {Value}";
            }
            else
            {
                Text = $"{Value} ({Unit})";
            }
        }
        else
        {
            base.UpdateEditText();
        }
    }

    /// <summary>
    /// Validate method called before actually updating the text.
    /// This is exactly the same as the base class but it will use the new ParseEditText from this class instead.
    /// </summary>
    protected override void ValidateEditText()
    {
        // See if the edit text parses to a valid decimal considering the label unit
        ParseEditText();
        UpdateEditText();
    }

    /// <summary>
    /// Converts the text displayed in the up-down control to a numeric value and evaluates it.
    /// </summary>
    protected new void ParseEditText()
    {
        try
        {
            // The only difference of this methods to the base one is that text is replaced directly
            // with the property Text instead of using the regex.
            // We now that the only characters that may be on the textbox are from the unit we provide.
            // because the NumericUpDown handles invalid input from user for us.
            // This is where the magic happens. This regex will match all characters from the unit
            // (so your unit cannot have numbers). You can change this regex to fill your needs
            var regex = new Regex($@"[^(?!{Unit} )]+");
            var match = regex.Match(Text);

            if (match.Success)
            {
                var text = match.Value;

                // VSWhidbey 173332: Verify that the user is not starting the string with a "-"
                // before attempting to set the Value property since a "-" is a valid character with
                // which to start a string representing a negative number.
                if (!string.IsNullOrEmpty(text) && !(text.Length == 1 && text == "-"))
                {
                    if (Hexadecimal)
                    {
                        Value = Constrain(Convert.ToDecimal(Convert.ToInt32(Text, 16)));
                    }
                    else
                    {
                        Value = Constrain(Decimal.Parse(text, CultureInfo.CurrentCulture));
                    }
                }
            }
        }
        catch
        {
            // Leave value as it is
        }
        finally
        {
            UserEdit = false;
        }
    }

    /// </summary>
    /// Returns the provided value constrained to be within the min and max.
    /// This is exactly the same as the one in base class (which is private so we can't directly use it).
    /// </summary>
    private decimal Constrain(decimal value)
    {
        if (value < Minimum)
        {
            value = Minimum;
        }

        if (value > Maximum)
        {
            value = Maximum;
        }

        return value;
    }

    #endregion
}

答案 3 :(得分:1)

这是我用来显示以0x为前缀的十六进制NumericUpDown的至少2位数字的方式。 它将文本放入控件中,并通过使用提供的.Net避免使用“反跳” 字段ChangingText

    class HexNumericUpDown2Digits : NumericUpDown
    {
        protected override void UpdateEditText()
        {
            if (Hexadecimal)
            {
                ChangingText = true;
                Text = $"0x{(int)Value:X2}";
            }
            else
            {
                base.UpdateEditText();
            }
        }
    }