Windows Develop Bookmark and Share   
 index > Windows Forms Data Controls and Databinding > Why InvalidateCell method doesn't fire Paint method for a customized DataGridViewCell?
 

Why InvalidateCell method doesn't fire Paint method for a customized DataGridViewCell?

I want to implement a customized DataGridViewCell so when my mouse is over the cell, its outlook changes. I found an article from MSDN teaching how to implement a DataGridViewRolloverCell: when you move mouse over the cell, its borders change color to red. The example works fine.

In the example, rows are added directly to the grid. I change the example so I use data binding to fill the grid. But after the change, I find a problem, after the form is opened, I move my mouse to a cell and its outlook doesn't get changed. Only after I select any cell of the same row does the cell's outlook changes when mouse is on it.

In the example code, there is a DataGridViewRolloverCell class. Its Paint, OnMouseEnter, OnMouseLeave methods are overriden. OnMouseEnter and OnMouseLeave methods only call InvalidateCell method. As explained in the documentation, when InvalidateCell is called, it forces the cell to repaint itself, thus the Paint method gets called. In the Paint method, the cell paints its borders in red color.

When the grid initializes and mouse enters a cell in a row such that no cell in that row has been selected before, InvalidateCell method of the cell gets called but the Paint method never gets fired. Only after I select the cell once, later on, the InvalidateCell method triggers the Paint method.

I guess it is related to some optimization of the grid when data binding is used but couldn't find the real answer as well as the solution. Anyone can help? Thank you.
Xiaonan Ji  Tuesday, August 18, 2009 11:50 PM
Hi Xiaonan Ji,

I don't know what code you have used to implement this effect. Here I have made a sample which can work for databinding situation. Please look at the following code.
public class MyDataGridView : DataGridView
{
private int mouseOverColIndex;
private int mouseOverRowIndex;
public MyDataGridView()
: base()
{
mouseOverColIndex = 0;
mouseOverRowIndex = 0;
}

protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == mouseOverColIndex && e.RowIndex == mouseOverRowIndex
&& (this.CurrentCell.ColumnIndex != mouseOverColIndex || this.CurrentCell.RowIndex != mouseOverRowIndex))
{
Rectangle rec = new Rectangle(e.CellBounds.Location.X, e.CellBounds.Location.Y, e.CellBounds.Width - 1, e.CellBounds.Height - 1);
e.Graphics.DrawRectangle(new Pen(new SolidBrush(Color.Blue), 2), rec);
e.PaintContent(e.ClipBounds);
e.Handled = true;
}
base.OnCellPainting(e);
}

protected override void OnCellMouseMove(DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex != mouseOverColIndex || e.RowIndex != mouseOverRowIndex)
{
mouseOverColIndex = e.ColumnIndex;
mouseOverRowIndex = e.RowIndex;
Refresh();
}
base.OnCellMouseMove(e);
}
}
I have overrieded the OnCellPainting and OnCellMouseMove method to draw a rectangle for the cell where your mouse is over. I am not sure this can meet your need. Hope you can get some help from this.

If you have anything unclear, please feel free to tell me.

Sincerely,
Kira Qian
Please mark the replies as answers if they help and unmark if they don't.
Kira Qian  Thursday, August 20, 2009 6:07 AM
Hi Xiaonan Ji,

I don't know what code you have used to implement this effect. Here I have made a sample which can work for databinding situation. Please look at the following code.
public class MyDataGridView : DataGridView
{
private int mouseOverColIndex;
private int mouseOverRowIndex;
public MyDataGridView()
: base()
{
mouseOverColIndex = 0;
mouseOverRowIndex = 0;
}

protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == mouseOverColIndex && e.RowIndex == mouseOverRowIndex
&& (this.CurrentCell.ColumnIndex != mouseOverColIndex || this.CurrentCell.RowIndex != mouseOverRowIndex))
{
Rectangle rec = new Rectangle(e.CellBounds.Location.X, e.CellBounds.Location.Y, e.CellBounds.Width - 1, e.CellBounds.Height - 1);
e.Graphics.DrawRectangle(new Pen(new SolidBrush(Color.Blue), 2), rec);
e.PaintContent(e.ClipBounds);
e.Handled = true;
}
base.OnCellPainting(e);
}

protected override void OnCellMouseMove(DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex != mouseOverColIndex || e.RowIndex != mouseOverRowIndex)
{
mouseOverColIndex = e.ColumnIndex;
mouseOverRowIndex = e.RowIndex;
Refresh();
}
base.OnCellMouseMove(e);
}
}
I have overrieded the OnCellPainting and OnCellMouseMove method to draw a rectangle for the cell where your mouse is over. I am not sure this can meet your need. Hope you can get some help from this.

If you have anything unclear, please feel free to tell me.

Sincerely,
Kira Qian
Please mark the replies as answers if they help and unmark if they don't.
Kira Qian  Thursday, August 20, 2009 6:07 AM

You can use google to search for other answers

Custom Search

More Threads

• DataGridView RowsAdded event goes off multiple times. Is this a bug?
• set background color DarkBlue for datagridview rows where column (quantity) = 0
• Datagridview ComboBox DropDown Menu is visble outside control
• bug? AutoSizeColumnsMode & header
• hierarchical dataviewgrids
• How to change row color in DataGrid?
• Advanced Issue: How to diagnose data not inserting or updating??
• OracleParameterCollection Problem
• DataGridView button click event
• Accessing DataGridView Index from Bound DataTable Index