DataGrid with a custom header and selection.
One of the questions that has recently come up on the .Net CF MSDN forums was on how to create a custom (owner drawn) header in the DataGrid. This person wanted to implement the look similar to the grid that is used in the Mobile CRM application that has a non standard header and row selection.
Both are using a gradient filled colors. So I decided to take this up for a challenge to create a similar look by using the standard DataGrid control that comes with .NET CF v2 SP2. Ilya Tumanov from the .NET CF team had create a great sample that shows how to create a custom column types and to override the Paint event in the DataGridTextBoxColumn. In my sample I've reused some code from his sample.
As a first step I have created the CustomSelectionColumn class that inherits from the DataGridTextBoxColumn. Here's how the Paint method looks:
protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source,
int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight)
{
RectangleF textBounds; // Bounds of text
object cellData; // Object to show in the cell
// Check if the row is selected
if (gridControl.IsSelected(rowNum))
{
DrawBackground(g, bounds, rowNum, backBrush, true);
}
else
{
DrawBackground(g, bounds, rowNum, backBrush, false);
}
// Draw cell background
bounds.Inflate(-2, -2); // Shrink cell by couple pixels for text.
textBounds = new RectangleF(bounds.X, bounds.Y, bounds.Width, bounds.Height);
// Set text bounds.
cellData = this.PropertyDescriptor.GetValue(source.List[rowNum]); // Get data for this cell from data source.
g.DrawString(FormatText(cellData), this.gridControl.Font, foreBrush, textBounds, this.StringFormat);
}
In order to draw a gradient filled selector in the grid, I went to the MSDN library samples for .NET CF and copied the code from the How to: Display a Gradient Fill article into my project. So the DrawBackround method utilizes the code from this article:
protected virtual void DrawBackground(Graphics g, Rectangle bounds, int rowNum, Brush backBrush, bool selected)
{
// Create rectangle for drawing
Rectangle rc = new Rectangle(bounds.Left - 2, bounds.Top, bounds.Width + 4, bounds.Height);
// Check if the row is selected
if (selected)
{
// Draw gradient cell selection
GradientFill.Fill(g, rc, Color.LightBlue, Color.RoyalBlue, GradientFill.FillDirection.TopToBottom);
}
else
{
g.FillRectangle(backBrush, rc);
}
}
So this should take care of a custom row selection. Now up to the custom header. A few years ago I had created an owner-drawn header control for a ListView. I have modified the CustomHeader control to use with the DataGrid and added the gradient drawing code to it. Here is the how the result looks:
You can download the full demo code from here.