c# 文本框数字格式不会丢失其第一个值

c# textbox number format without lose its first value

我有一个带有文本框的 winform 项目。我将使用这些文本框进行数学运算。在文本框中,我想显示没有点的数字。例如;

号码:123.384243333333333;

显示格式:123

所以我使用了下面的代码。

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

但是数学计算必须是presize。如果我想达到文本框值

string Width= textbox1.Text;

宽度值为 123。但我想达到第一个值,即 123.384243333333333。 所以格式化后结果失去了精度。我怎样才能保持第一个值?

我使用标签 属性 进行其他操作。所以我不能用。

DataGirdView 控件通过 cellformatting 事件为我们提供了这个机会。单元格显示没有点的值,但单元格保留真实(第一个)值。我正在搜索类似的东西。

在文本框的“标记”属性 中保留初始值并将其用作实际值:

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

NumericUpDown

分别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

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

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

或者,subclass设置默认值:

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


文本框

如果旋转框不是一个选项,您需要使用 TextBox。新建一个class并继承TextBox控件,添加一个小数属性来存储真实值并使用它的setter将值的整数部分赋值给Text 属性。如果您允许文本 edit/paste.

,您还需要重写 OnValidating 方法来验证输入,如下所示
[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);
}

使用此自定义 TextBox,忘记 Text 属性 并使用 Value 属性 到 set/get 值。