简体   繁体   中英

.Net C# WinForm DataGridView - TextBox Cell: what's the best way to update/change from a numeric user input to a specific culture currency?

A. BACKGROUND OF THE QUESTION

I am trying to have a cell in a datagridview to accept a numeric only user input, which I've handled on the Grid's EditingControlShowing event and the textbox cell's KeyPress event. Now, after the user hits enter or leaves the focus from that cell, I would like to update the cell's value to have a decimal separator and the specific culture currency. The following is the flow that I'm trying to explain:

  1. numeric user input on a datagridview cell -> done (NOTE: cell's ValueType == int || double already).

  2. on cell's leave focus, update the cell value to have decimal separator and specific currency symbol from a culture, to display. (The reason to have a specific culture so that if the application is installed on a different machine with different culture, it will stay on that specific culture).

  3. on cell's enter focus or editing, i would like to strip all of that separators and currency symbol and go back to the numeric only user input value.

B. THE QUESTIONS

  1. First of all, is there a way to implement this without using the CellFormatting event? (I would like to prefer to avoid using this event because this event is called so often and I don't want to put burden on the performance already).

  2. I already use the following:

     NumberFormatInfo numberFormat = CultureInfo.CreateSpecificCulture("de-DE").NumberFormat; double d = double.Parse(<value>, numberFormat); string test = d.ToString(numberFormat); 

But, it doesn't really updates the value, what do I miss here?

  1. what's the best way to implement the behavior, for example, is the cellValueChanged event and CellEnter event will be the best events to handle the above behavior? or CellValidated and CellEnter events will be best events?

Basically, I'm confused on which event is the best event to handle the behavior (without being called so often such as CellFormatting event which is called every time the grid is painted or basically every time you touch the grid), and how to enforce the NumberFormatInfo to that string value.

Thanks!

EDIT (15/09/2016): I actually can update the value to what I want, by doing this:

string test = d.ToString("c2", numberFormat);

I thought the numberFormat itself is sufficient to applying the format because it has the information, but I actually have to explicitly specifying the format such as "c2" from above example, and it acts like a "command" which take the information from a "dictionary" which in this case the "numberFormat" (the definition).

So, this is how it works for me:

  1. I added DataGridViewColumn programmatically, so when I create those columns, I setup these properties:

     DataGridViewTextBox column = new DataGridViewTextBoxColumn(); ... column.ValueType = typeof(decimal); column.DefaultCellStyle.Format = "c2"; column.DefaultCellStyle.FormatProvider = CultureInfo.CreateSpecificCulture("de-DE").NumberFormat; 
  2. Handle on the DataGridView EditingControlShowing event, to remove the Currency Symbol and to only shows the number only during editing the cell's value:

     public void Grid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { ... if(decimal.TryParse(grid.EditingControl.Text, NumberStyles.Currency, CultureInfo.CreateSpecificCulture("de-DE").NumberFormat, out decimalValue)) { grid.EditingControl.Text = decimalValue.ToString("#", CultureInfo.CreateSpecificCulture("de-DE").NumberFormat); } ... } 
  3. Handle on the `CellValidating' event, to make sure the user input value is in proper format (or in numeric only):

     public void Grid_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) { ... //No need to check/validate the new row if (gridSender.Rows[e.RowIndex].IsNewRow) { return; } ... if(!decimal.TryParse(value, NumberStyles.Currency, CultureInfo.CreateSpecificCulture("de-DE").NumberFormat, out result)) { e.Cancel = true; } ... } 

NOTE: if you do step #1 above (ie "c2" and specifying the FormatProvider ), then it will automatically shows the Currency Symbol and the decimal points, every time the user leave focus of the cell of that column. So, the only thing needs to do, is stripping the currency symbol and how to show the value in numeric only by doing step #2. Step #3, is just another validation to make sure the input is numeric.

Example Flow:

  1. users click on the cell and in edit more, it will display 1000
  2. user click on another cell or focus away, it will display $1.000,00
  3. user click on the cell again and in editing, it will display 1000

The above solutions works good enough for me.

Why is having a culture currency symbol such a big deal for you Jay??? Also why are decimal points such a big deal??? Can the program work without these and achieve the same goal??? Would it not be better to determine the culture symbol of the currency at the outset in the program and possibly use it as a variable and append it later to the string?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM