Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

.NET CF Custom DataGrid Formatting

0.00/5 (No votes)
29 Aug 2007 5  
This article shows you how to customize individual cells in a DataGrid - and it works on the Compact Framework.

Screenshot - GridSample.png

Introduction

The DataGrid is a powerful control in the Compact Framework, but it's not easy to work out how to apply individual formatting to cells with control over why and how each cell is 'customized'.

This expands on a very good article here written by Mazdak, which nearly did everything I needed, but didn't quite allow enough customization 'logic'.

Important Reading

There are some important caveats before using this code, the most important of which is ensuring that the correct version of the .NET Compact Framework is installed. I will say this very carefully - you need .NET CF Version 2 Service Pack 2.

The SP2 part is the important bit, as this release introduced the Paint event of the DataGridTextBoxColumn class as virtual, thus allowing us to override the event and produce the effects we need.

You can get the right version of the Framework from here.

How it Works

I take very little credit for the code contained within, as most of the various parts of this 'approach' can be readily found online. The tough bit (for me at least) was in pulling it together into a reusable and flexible approach that could provide proper formatting of the control.

The basic approach is to build a class that inherits from DataGridTextBoxColumn which can then be applied to the table styles of the grid. This class contain three important elements: there is a property which contains the column number, a number of (1 or more) events, and an override of the Paint event.

The event is a slightly customized one; we use a simple class that inherits from EventArgs that allows the result of the event to contain a row, a column, and a boolean value.

The basic plan is to signal an event from within the Paint event which waits for a returning result of type DataGridEnableEventArgs. We check the boolean property (I have called it meetsCriteria) and 'paint' the cell accordingly.

The code below shows a simple version of this. CheckCellEven is one of our events; we first check to see that its not null for the ColumnStyle, and if not, we raise the event. The event returns with a boolean (based on some logic in the subscribing event), and in this case, we change the BackBrush color, but we have full access to the graphics canvas and can draw lines, strings, etc., in the same way we can in any other Paint event.

protected override void Paint(Graphics g, Rectangle Bounds, CurrencyManager Source, 
                   int RowNum, Brush BackBrush, Brush ForeBrush, bool AlignToRight)
{
    if (CheckCellEven != null)
    {
        DataGridEnableEventArgs e = new DataGridEnableEventArgs
                (RowNum, _col, enabled);
        CheckCellEven(this, e);
        if (e.MeetsCriteria)
            BackBrush = new SolidBrush(Color.Orange);
    }

    base.Paint(g, Bounds, Source, RowNum, BackBrush, ForeBrush, AlignToRight);
}

It's a simple approach that allows multiple formatting styles to be applied to individual cells. The subscribing event can be in the same class that contains the DataGrid and therefore has full access to the DataGrid itself as well as to any other control or variable. This allows almost limitless logic to be used in determining whether to paint each cell in a certain way.

Using the Code

After the grid control is filled with data (in this case, from the SDK Northwind sample), using the code is not relevant to the article.

Next, we instantiate a ColumnStyle class for each column we have in our DataSet. I have included a few ways of determining which columns fire subscribe to which events and a few ways that the event can determine the result.

Remember that our ColumnStyle class inherits from DataGridTextBoxColumn so we add each instance of the class to an instance of a DataGridTableStyle class before adding the DataGridTableStyle to DataGrid.Tables.Styles.

I have used an anonymous method to wire up an event which is worth looking at.

In the code below, we check DataTable.Column and check its data type; if its an int, we add the event handler using an anonymous method and a delegate. In this case, we simply check if the cell we are painting contains the value 2.

if (dt.Columns[i].DataType == System.Type.GetType("System.Int32"))
    myStyle.CheckCellEquals += 
      delegate(object sender, DataGridEnableEventArgs e)
      {
        e.MeetsCriteria = ((int)dataGrid1[e.Row, e.Column] == 2) ? 
        true : false;
      };

Not a Finished Example

Before anyone moans, this sample is designed to show an approach to something that I found difficult to do. There is no error checking on any of the casts that get made, and it's far from robust if you use different data. The approach will work in any scenario in which a DataGrid is used, and can be expanded to build very complex grids.

Don't be put off by the size of the download, it's mainly the Northwind database, as I didn't want to spend time populating the grid control and this was the easiest way to do it. The actual code is in two files and contains only three classes and a handful of methods, and the implementation is really very simple.

This is just a simple sample that I wanted to put together to show the approach. It will not be developed any further.

History

  • 29 August, 2007: Initial post.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here