Wow, this was harder than it should have been, maybe. As usual, I just didn't feel like digging into the dirty details, so maybe it makes plenty of sense. Anyway, I had a DataGridCheckBoxColumn that when checked, I wanted to "disable" some other cells (check indicates the user is an administrator and other settings do not apply). To disable, I set the ReadOnly property for each cell and the Style.BackColor to gray. However, the BackColor change just wasn't happening, and then it was happening, but not until the check cell lost focus, and so on. Finally, the oh-so-important EndEdit call did the trick.
/// <summary>
/// Event handler for when cell content is clicked. Specifically, we are checking if the Administrator
/// checkbox state is changed and refreshing the grid so the un-necessary cells are disabled and
/// grayed-out (via the subsequent CellFormatting event).
/// </summary>
private void OnCellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (theGrid.Columns[e.ColumnIndex] != ColumnAdminCheckBox)
return;
theGrid.EndEdit(); // VERY important call or the repaint doesn't happen until the cell loses focus.
theGrid.Refresh();
}
/// <summary>
/// Event handler for when cell content is formatted. Specifically, we are checking the state of the
/// Administrator checkbox and setting the ReadOnly and BackColor of the cells that do not apply when
/// user is an administrator.
/// </summary>
void OnCellFormatting(object sender, System.Windows.Forms.DataGridViewCellFormattingEventArgs e)
{
// Only update certain columns
DataGridViewColumn column = theGrid.Columns[e.ColumnIndex];
if (column != ColumnA && column != ColumnB &&
column != ColumnC)
return;
object obj = theGrid[theGrid.Columns.IndexOf(ColumnAdminCheckBox), e.RowIndex].Value;
if (obj == null || obj.GetType() != typeof(bool))
return;
bool admin = (bool)obj;
theGrid[e.ColumnIndex, e.RowIndex].ReadOnly = admin;
e.CellStyle.BackColor = (admin ? theGrid.BackgroundColor : Color.White);
}