Reputation: 497
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
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; }
}
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);
}
Using this custom TextBox
, forget the Text
property and use instead the Value
property to set/get the values.
Upvotes: 1
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