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'.
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
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
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);
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
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"))
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.
- 29 August, 2007: Initial post.