CurrencyTextBox 在第一次加载时不格式化文本

CurrencyTextBox does not format the text on first load

我正在使用 C# 为 windows 应用程序创建 CurrencyTextBox。快完成了,但是当 CurrencyTextBox 显示其文本时我遇到了问题。它不是货币格式。例如:

20000 it should be displayed as ,000.00

为了显示为 $20,000.00,我必须调用格式化代码。

private void Form1_Load(object sender, EventArgs e)
{
    currencyTextBox1.Value = 20000;
    currencyTextBox1.Text = currencyTextBox1.Value.ToString("C");
}

还有其他方法可以简化这个问题吗?

下面是 CurrencyTextBox 的代码:

public class CurrencyTextBox : TextBox
{
    private decimal _value = 0;

    public CurrencyTextBox()
    {
        base.TextAlign = HorizontalAlignment.Right;
    }

    protected override void OnEnter(EventArgs e)
    {
        base.OnEnter(e);

        this.Text = _value.ToString();

        if (this.Text == "0")
            this.Clear();

        this.SelectionStart = this.Text.Length;
    }

    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        base.OnKeyPress(e);

        NumberFormatInfo numberFormatInfo = CultureInfo.CurrentCulture.NumberFormat;
        string decimalSeparator = numberFormatInfo.NumberDecimalSeparator;
        string groupSeparator = numberFormatInfo.NumberGroupSeparator;
        string negativeSign = numberFormatInfo.NegativeSign;

        // Workaround for groupSeparator equal to non-breaking space 
        if (groupSeparator == ((char)160).ToString())
        {
            groupSeparator = " ";
        }

        // Allows only numbers, decimals and control characters
        if (!Char.IsDigit(e.KeyChar) && !Char.IsControl(e.KeyChar) && e.KeyChar != decimalSeparator[0])
        {
            e.Handled = true;
        }

        if (e.KeyChar == decimalSeparator[0] && this.Text.Contains(decimalSeparator[0]))
        {
            e.Handled = true;
        }

        if (e.KeyChar == decimalSeparator[0] && this.Text.Length < 1)
        {
            e.Handled = true;
        }
    }

    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);

        try
        {
            Value = Convert.ToDecimal(this.Text);
        }
        catch { }
    }

    protected override void OnValidated(EventArgs e)
    {
        base.OnValidated(e);

        try
        {
            // format the value as currency
            decimal dTmp = Convert.ToDecimal(this.Text);
            this.Text = dTmp.ToString("C");
        }
        catch { }
    }

    public decimal Value
    {
        get { return this._value; }
        set { this._value = value; }
    }
}

您应该使用 textChanged 事件,因此当您赋值时会应用格式。

public Form1()
        {
            InitializeComponent();
            textBox1.Text = "20000";
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            FormatText();
        }

        private void FormatText()
        {
            if (String.IsNullOrWhiteSpace(textBox1.Text)) // Validate input
                return; 
            decimal amount;
            Decimal.TryParse(textBox1.Text, out amount);
            if (amount == 0) // Validate if it's a number
                return;
            textBox1.Text = "$" + String.Format("{0:n0}",amount); // Format with no decimals
            textBox1.Select(textBox1.Text.Length, 0); // Set the cursor position to last character
        }

简单 TextBox 没有 属性 可以设置货币格式的地方。但是,您可以使用一些方法将 TextBox 文本格式化为正确的格式。

1) 创建自定义控件并继承 TextBox,您可以在其中覆盖 TextBoxText 属性 并进行更改。

public shadow string Text
{
    get{
        return base.Text.Replace("$", "").Replace(",","");
    }
    set{
        base.Text = Convert.ToDecimal(value).ToString("C");
    }
}

2) 如果您不想创建自定义控件,那么您可以在表单中定义一个 属性 并使用它 属性 而不是 TextBox 的文本 属性.

public shadow string AmountText
{
    get{
        return txtAmount.Text.Replace("$", "").Replace(",","");
    }
    set{
        txtAmount.Text = Convert.ToDecimal(value).ToString("C");
    }
}

注意:这只是为了创造想法。您需要将代码修改为 return 并正确设置值。

保留所有原始代码,我更改了两处,一切似乎都运行良好:

protected override void OnTextChanged(EventArgs e)
{
  base.OnTextChanged(e);

  try
  {
    this._value = Convert.ToDecimal(this.Text); // Assign private field instead of property, due to the next change.
  }
  catch { }
}

public decimal Value
{
  get { return this._value; }
  set 
  { 
    this._value = value;
    this.Text = this._value.ToString("C"); // Set the text when Value is set.
  }
}

那么你的用法就这么简单:

private void Form1_Load(object sender, EventArgs e)
{
  currencyTextBox1.Value = 20000;
}