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);
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);
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.

Comments (9)

  1. bnaya says:

    the link for the source is missing

  2. DataGrid with a custom header and selection

  3. Chi, guardando qualche affascinente demo, non è rimasto colpito dalla grafica usata nelle applicazioni

  4. cf_joe says:


    I know this request might be kinda of far but I using your code for displaying images on the header of Listview(,category,ListView%20header.aspx ) but I also need to display images on the subitems (2 or 3 col) I am don’t know the correct sendmessage to enable the Listview to get an handle to ListView and also set the image on certain columns of Subitem ListView. Can you kindly point me in the right direction.


  5. selmaguzel says:


    I tried your code for displaying images on the listview(,category,ListView%20header.aspx).

    But when i try to this for datagrid, i got error as there is not a handler for datagrid.I changed the same code for datagrid only.


    how can i display image on the datagrid column header?

    Is it possible?


  6. ghb9812052 says:


    the link for demo code is missing.

    Can you send me ?


  7. avicool08 says:


    suppose, I have a datagrid column which is combobox column.

    Now, on button click, i want to loop and save all moidified data.

    How to do this, please.

  8. EcoGuy says:

    Thanks for this Header component. It's exactly what I needed.

    Little display mistakes though:

    1) dataGrid1.Top = 21. // Should be 22, because the header height is 22. Otherwise the first row displays badly

    2) In HeaderControl class, in OnPaint method, you should count for the divide width itself when setting the position of the next header. Note: I've used a divider of 1 pixel wide (instead of 2 for you), thus:

    instead of

       // position += header.Width;


       position += header.Width + 1; // +1 stands for the divider width itself

    2) in CustomSelectionColumn class, in DrawBackGround method, the drawing rectangle is too wide.

        I guess it's a "left over" of previous attempts, where the DrawBackGround was called after the Inflate(-2,-2)

    Anyway, do this:

       //Rectangle rc = new Rectangle(bounds.Left – 2, bounds.Top, bounds.Width + 4, bounds.Height);

       Rectangle rc = new Rectangle(bounds.Left, bounds.Top, bounds.Width, bounds.Height);

    I've seen these 2 last issues when I allowed the DataGrid to display its GridLines

  9. EcoGuy says:

    Another bug:

    In HeaderControl.cs, in OnMouseDown, the test rectangle top is wrong

    //Rectangle headerRect = new Rectangle(header.Left, this.Top, header.Width, this.Height);

    should be:

    Rectangle headerRect = new Rectangle(header.Left, 0, header.Width, this.Height);

    (btw, the was a bit strange, as there were no this.Left for the x coordinate)

    This is because the e.y coordinate is relative to the component top itself (it's not a screen coordinate)

    It worked fine because the grid is on top of the screen.