Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having text inside NumericUpDown control, after the number

Is it possible in WinForms to show a text inside a NumericUpDown control? For example I want to show the value in my numericupdown control is micro ampers so it should be like "1 uA".

Thanks.

like image 919
Saeid Yazdani Avatar asked May 07 '11 13:05

Saeid Yazdani


People also ask

What is the property that determines by how much the current number in a NumericUpDown control changes when the user clicks the up arrow or the down arrow?

The Increment property sets the amount that the number is adjusted by when the user clicks an up or down arrow.

What is the meaning of numeric up down control?

A NumericUpDown control contains a single numeric value that can be incremented or decremented by clicking the up or down buttons of the control. The user can also enter in a value, unless the ReadOnly property is set to true .

How do I change NumericUpDown value?

To set the numeric valueAssign a value to the Value property in code or in the Properties window. Call the UpButton or DownButton method to increase or decrease the value by the amount specified in the Increment property.

How do you use numeric up down in Visual Basic?

Drag and drop NumericUpDown Control from the toolbox on window Form. By Default Maximum and Minimum value in NumericUpDown Control is set 100 and 0 respectively. You can also set Maximum and Minimum value in NumericUpDown Control. To show the value in NumericUpDown.


2 Answers

There's no such functionality built into the standard control. However, it's fairly easy added by creating a custom control that inherits from the NumericUpDown class and overrides the UpdateEditText method to format the number accordingly.

For example, you might have the following class definition:

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";
    }
}

Or, for a more complete implementation, see this sample project: NumericUpDown with unit measure

like image 75
Cody Gray Avatar answered Sep 18 '22 12:09

Cody Gray


Using CodeGray's answer, Fabio's comment about it failing ValidateEditText, and the NumericUpDown documentation I've come up with a simple NumericUpDownWithUnit component. You can copy/paste as is:

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
}
like image 43
Thales Gaddini Avatar answered Sep 18 '22 12:09

Thales Gaddini