Gokhan
Gokhan

Reputation: 497

c# textbox number format without lose its first value

I have winform Project that have textboxes. I will use these textboxes for mathematical operations. In textboxes I want to display numbers without dot. For-ex;

number : 123.384243333333333;

display format : 123

So i used codes below.

string result = (height * rate).ToString();
textbox1.Text = String.Format("{0:N0}", result);

But math calculations must be presize. If i want to reach textbox value

string Width= textbox1.Text;

Width value will be 123. But i want to reach the first value which is 123.384243333333333. So after formatting result loses its precision. How can i keep first value?

I used tag property for another actions. So i can not use.

DataGirdView control gives us this opportunity with cellformatting event. Cell displays value without dot, but cell keeps the real(first) value. I am searching something like that.

Upvotes: 1

Views: 654

Answers (2)

dr.null
dr.null

Reputation: 4695

NumericUpDown

The NumericUpDown is supposed to be the default choice for this problem where you can keep the real value and control what to display. In your case, set the DecimalPlaces property to 0 (the default value) and set the Minimum and Maximum properties to the Decimal.MinValue and Decimal.MaxValue respectively.

public YourForm()
{
    InitializeComponent();
            
    numericUpDown1.Maximum = decimal.MaxValue;
    numericUpDown1.Minimum = decimal.MinValue;
    numericUpDown1.DecimalPlaces = 0; // Default...

    // The same for the other numeric controls...
}

Or, subclass to set the default values:

public class MyNumericUpDown : NumericUpDown
{
    public MyNumericUpDown()
    {
        Minimum = decimal.MinValue;
        Maximum = decimal.MaxValue;
    }

    /// <inheritdoc cref="NumericUpDown.Minimum"/>
    [DefaultValue(typeof(decimal), "-79228162514264337593543950335")]
    public new decimal Minimum { get => base.Minimum; set => base.Minimum = value; }

    /// <inheritdoc cref="NumericUpDown.Maximum"/>
    [DefaultValue(typeof(decimal), "79228162514264337593543950335")]
    public new decimal Maximum { get => base.Maximum; set => base.Maximum = value; }
}

SOQ68431065A


TextBox

If the spin box is not an option and you need to use a TextBox. Create a new class and inherit the TextBox control, add a decimal property to store the real value and use it's setter to assign the integral part of the value to the Text property. Also you need to override the OnValidating method to validate the inputs as shown below if you allow text edit/paste.

[DefaultEvent("ValueChanged")]
[DefaultProperty("Value")]
[DesignerCategory("Code")]
public class IntTextBox : TextBox
{
    public IntTextBox() : base()
    {
        //Comment if you allow text edit/paste...
        ReadOnly = true;
        BackColor = SystemColors.Window;
    }

    private decimal _value;
    [DefaultValue(typeof(decimal), "0")]
    public decimal Value
    {
        get => _value;
        set
        {
            if (_value != value)
            {
                _value = value;
                Text = Math.Truncate(value).ToString();
                OnValueChanged(EventArgs.Empty);
            }
        }
    }

    protected override void OnValidating(CancelEventArgs e)
    {
        base.OnValidating(e);

        if (ReadOnly) return;
        // Change as required...
        if (Text.Trim().Length == 0) Value = 0;
        else if (decimal.TryParse(Text, out var res))
        {
            if (res % 1 != 0 && res != _value) Value = res;
            else if (res != Math.Truncate(_value)) Value = res;
        }
        else
            Text = Math.Truncate(Value).ToString();
    }

    // Handle this in the host instead of the TextChanged event if you need so...
    public event EventHandler ValueChanged;

    protected virtual void OnValueChanged(EventArgs e) =>
        ValueChanged?.Invoke(this, e);
}

SOQ68431065B

Using this custom TextBox, forget the Text property and use instead the Value property to set/get the values.

Upvotes: 1

Mansur Qurtov
Mansur Qurtov

Reputation: 772

Keep Initial values in "Tag" property of your textbox and use from it as actual value:

 
double result = height * rate;
textbox1.Text = String.Format("{0:N0}", result.ToString());
textbox1.Tag = result;
//...
double actualValue = double.Parse(textbox1.Tag.ToString());

Upvotes: 0

Related Questions