adding a sign to numericUpDown value (like %)

混江龙づ霸主 提交于 2019-12-05 10:02:22

You can create your own custom NumericUpDown class and override the UpdateEditText method like so:

Create a new class with the name CustomNumericUpDown and put this code in the class.

public class CustomNumericUpDown : NumericUpDown
{
  protected override void UpdateEditText()
  {
    this.Text = this.Value.ToString() + "%";
  }
}

Remember to add using System.Windows.Forms;. And whenever you want to add it to your form. You use

CustomNumericUpDown mynum = new CustomNumericUpDown();

We need to write own control and use it if we want different "output".

public class MyNumericUpDown : NumericUpDown
{
    protected override void UpdateEditText()
    {
        base.UpdateEditText();

        ChangingText = true;
        Text += "%";
    }
}

@Kenji If we only set Text property we lose some functionality (eg. Hexadecimal or DecimalPlaces)

If someone is searching for a complete solution, here is one:

using System;
using System.Windows.Forms;
using System.Globalization;
using System.Diagnostics;
using System.ComponentModel;


/// <summary>
/// Implements a <see cref="NumericUpDown"/> with leading and trailing symbols.
/// </summary>
public class NumericUpDownEx : NumericUpDown
{

    /// <summary>
    /// Initializes a new instance of <see cref="NumericUpDownEx"/>.
    /// </summary>
    public NumericUpDownEx()
    { }

    private string _leadingSign = "";
    private string _trailingSign = "";

    /// <summary>
    /// Gets or sets a leading symbol that is concatenate with the text.
    /// </summary>
    [Description("Gets or sets a leading symbol that is concatenated with the text.")]
    [Browsable(true)]
    [DefaultValue("")]
    public string LeadingSign
    {
        get { return _leadingSign; }
        set { _leadingSign = value; this.UpdateEditText(); }
    }

    /// <summary>
    /// Gets or sets a trailing symbol that is concatenated with the text.
    /// </summary>
    [Description("Gets or sets a trailing symbol that is concatenated with the text.")]
    [Browsable(true)]
    [DefaultValue("")]
    public string TrailingSign
    {
        get { return _trailingSign; }
        set { _trailingSign = value; this.UpdateEditText(); }
    }

    protected override void UpdateEditText()
    {
        if (UserEdit)
        {
            ParseEditText();
        }

        ChangingText = true;
        base.Text = _leadingSign + GetNumberText(this.Value) + _trailingSign;
        Debug.Assert(ChangingText == false, "ChangingText should have been set to false");
    }

    private string GetNumberText(decimal num)
    {
        string text;

        if (Hexadecimal)
        {
            text = ((Int64)num).ToString("X", CultureInfo.InvariantCulture);
            Debug.Assert(text == text.ToUpper(CultureInfo.InvariantCulture), "GetPreferredSize assumes hex digits to be uppercase.");
        }
        else
        {
            text = num.ToString((ThousandsSeparator ? "N" : "F") + DecimalPlaces.ToString(CultureInfo.CurrentCulture), CultureInfo.CurrentCulture);
        }
        return text;
    }

    protected override void ValidateEditText()
    {
        ParseEditText();
        UpdateEditText();
    }

    protected new void ParseEditText()
    {
        Debug.Assert(UserEdit == true, "ParseEditText() - UserEdit == false");

        try
        {
            string text = base.Text;
            if (!string.IsNullOrEmpty(_leadingSign))
            {
                if (text.StartsWith(_leadingSign))
                    text = text.Substring(_leadingSign.Length);
            }
            if (!string.IsNullOrEmpty(_trailingSign))
            {
                if (text.EndsWith(_trailingSign))
                    text = text.Substring(0, text.Length - _trailingSign.Length);
            }

            if (!string.IsNullOrEmpty(text) &&
                !(text.Length == 1 && text == "-"))
            {
                if (Hexadecimal)
                {
                    base.Value = Constrain(Convert.ToDecimal(Convert.ToInt32(text, 16)));
                }
                else
                {
                    base.Value = Constrain(decimal.Parse(text, CultureInfo.CurrentCulture));
                }
            }
        }
        catch
        {

        }
        finally
        {
            UserEdit = false;
        }
    }

    private decimal Constrain(decimal value)
    {
        if (value < base.Minimum)
            value = base.Minimum;

        if (value > base.Maximum)
            value = base.Maximum;

        return value;
    }

}

The solution was not working for me as I was getting unexpecting behavior when I was editing the numericupdown. For instance, I could not change one number and save the result, because the text was containing the trailing character ('%' in the question, '€' in my case).

So I update the class with some code to parse the decimal and store the value. Note the use of ChangingText otherwise it was triggering modification event in loops

class EuroUpDown : NumericUpDown
{
    protected override void UpdateEditText()
    {
        ChangingText = true;
        Regex decimalRegex = new Regex(@"(\d+([.,]\d{1,2})?)");
        Match m = decimalRegex.Match(this.Text);
        if (m.Success)
        {
            Text = m.Value;

        }
        ChangingText = false;

        base.UpdateEditText();
        ChangingText = true;

        Text = this.Value.ToString("C", CultureInfo.CurrentCulture);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!