If the grid’s data source is to be set, then… maybe… you could throw this into the grids CellFormating
event. However, it should be clear that in the long run, the cell will get formatted many-many more times than necessary. I think we can do better. We can not “format” the cell until either 1) the user changes the Currency
cell, or 2) new data is loaded into the grid.
The first part is trivial… wire up the grids CellValueChanged
event. If the cell value that changed is a Currency
cell… then, check the "new" value and format the Price
cell accordingly.
This works when the user changes a Currency
cells value, however, it does not work when the data is loaded. Therefore, a simple loop through the grid’s rows should solve that issue. Since we need to set the Price
cells format in two different places, I suggest creating a method that takes a DataGridViewRow
and formats the “Price” cell for the given row. It may look something like…
private void FormatAmountCell(DataGridViewRow row) {
if (!row.IsNewRow && row.Cells["Currency"].Value != null) {
string currency = row.Cells["Currency"].Value.ToString();
DataGridViewCell cellToFormat = row.Cells["Price"];
switch (currency) {
case "EUR":
cellToFormat.Style.FormatProvider = CultureInfo.GetCultureInfo("en-GB");
break;
default:
cellToFormat.Style.FormatProvider = CultureInfo.GetCultureInfo("en-US");
break;
}
}
}
With this helper we can then use it in the grids wired up CellValueChanged
event.
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
FormatAmountCell(dataGridView1.Rows[e.RowIndex]);
}
In addition, a small method that loops through the grids rows and sets each “Price” cells format. We will call this after the data is loaded into the grid.
private void FormatAmountCellForAllRows() {
foreach (DataGridViewRow row in dataGridView1.Rows) {
FormatAmountCell(row);
}
}
Putting all this together for testing may look something like…
DataTable GridTable;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
GridTable = GetData();
dataGridView1.DataSource = GridTable;
dataGridView1.Columns["Price"].DefaultCellStyle.Format = "c";
FormatAmountCellForAllRows();
}
private DataTable GetData() {
DataTable dt = new DataTable();
dt.Columns.Add("Price", typeof(decimal));
dt.Columns.Add("Currency", typeof(string));
Random rand = new Random();
for (int i = 0; i < 10; i++) {
dt.Rows.Add(rand.NextDouble() * 100, (rand.Next(2) == 0 ? "USD" : "EUR"));
}
return dt;
}
Now you can sleep well knowing the formatting is never done unnecessarily.