1
votes

I have a function that formats a textbox value to currency. I did this in Textbox Leave event.

private void txtSellingPrice_Leave(object sender, EventArgs e)
{
  txtSellingPrice.Text = FormatCurrency(txtSellingPrice.Text);
}

Example a user enters 100, the output will be $100.

My question is how will I do it in datagridview cell? i already tried adding leave event in editing control. I also tried DefaultCellStyle.Format = "C2", this works but when the user change the current value, say $100.00 change to 50. The output should be $50.00. Thanks.

1
You should consider using a NumericBox instead of TextBox, aswell in your DataGrid use a NumericColumn instead of a TextColumn. The Numeric specific controls are designed to do exactly what you want. - Rand Random
thanks, but i think NumericBox is a custom control. It's not available in my toolbox. I'm using Visual Studio 2015. The one available is numericUpDown control. - Zhyke
If I create a simple DataGridView with a BindingSourc and a BindingListView. The column's DevaultCellStype = C2, then the values are displayed as $ 50.00, during typing people may change this into 12.346, but as soon as the cell is left it is automatically changes into $ 12.35. Isn't this what you wanted? - Harald Coppoolse
@HaraldCoppoolse yes, but mine is not doing that. If i type 100 after the cell was left no change. value is still 100. My datagridview has no datasource. I am allowing user to input value in the datagridview. - Zhyke

1 Answers

0
votes

The easy method would be assigning a BindingSource to your DataGridView and a BindingList to your BindingSoure. Set the default cell style format of the column that displays the currency to C2.

If you've done that, any added / changed / removed cell of your currency column will automatically be formatted.

However, if you don't want to use the BindingSource, you'll have to do the formatting yourself. Use events DataGridViewCell.CellValidating and DataGridViewCell.CellFormating.

Let's assume you have a columnCurrency, with a decimal value that should be dislayed in format C2. The DefaultCellFormat is set to C2.

Upon validating the cell, check if the value is really a decimal:

private void OnCellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
    if (e.RowIndex == -1) return;
    if (e.ColumnIndex == this.columnValue.Index)
    {
        decimal value;
        e.Cancel = !Decimal.TryParse((string)e.FormattedValue, out value);
    }
}

Whenever the cell must be formatted, format the value in e.Value:

private void OnCellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    if (e.ColumnIndex == this.columnValue.Index)
    {
        if (e.Value == null)
        {   // show the Null value:
            e.Value = e.CellStyle.NullValue;
            e.FormattingApplied = true;
        }
        else
        {   // because validated I know value is a decimal:
            decimal value = Decimal.Parse((string)e.Value);
            e.Value = value.ToString(e.CellStyle.Format);
            e.FormattingApplied = true;
        }

        // If desired apply other formatting, like background colouring etc
    }
}

If you don't want to use "C2" as currency format, and prefer to use your function FormatCurrency you'll have to create a FormatProvider that uses FormatCurrency to Format and set the FormatProvider of the DefaultCellStyle

 private void OnCellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    if (e.ColumnIndex == this.columnValue.Index)
    {
        ... (check for null value as described above)
        else
        {
            e.Value = String.Format(e.Value, e.CellStyle.FormatProvider);
            e.FormattingApplied = true;