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.

crm_mobile

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:

custom_grid

You can download the full demo code from here.

Comments

  • Anonymous
    November 11, 2007
    the link for the source is missing

  • Anonymous
    November 13, 2007
    DataGrid with a custom header and selection

  • Anonymous
    November 13, 2007
    Chi, guardando qualche affascinente demo, non รจ rimasto colpito dalla grafica usata nelle applicazioni

  • Anonymous
    April 04, 2008
    Alex, I know this request might be kinda of far but I using your code for displaying images on the header of Listview(http://blog.opennetcf.org/ayakhnin/CategoryView,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. Thanks,

  • Anonymous
    August 26, 2008
    Hi, I tried your code for displaying images on the listview(http://blog.opennetcf.com/ayakhnin/CategoryView,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. Then, how can i display image on the datagrid column header? Is it possible? Thanks.

  • Anonymous
    October 05, 2008
    Hi the link for demo code is missing. Can you send me ? hbguo@wind.com.cn thanks!

  • Anonymous
    July 20, 2009
    Hi 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.

  • Anonymous
    January 09, 2014
    The comment has been removed

  • Anonymous
    January 13, 2014
    The comment has been removed