DataGrid extensions for the Compact Framework
InfoDabble > Tech Notes > DataGrid extensions for the Compact Framework
By Eric Hartwell -- February 25, 2008
Microsoft says, "The DataGrid class in the .NET Compact Framework provides the core functionality of the Windows Forms DataGrid class in the full .NET Framework." That's a bit like saying a rock provides the core functionality of a nuclear submarine.
The Compact Framework provides a subset of the functionality of the full .NET Framework. That's what makes it compact. Ok, but ...
- <rant>did it never occur to anyone at Microsoft that the user interface is even more important in mobile applications than in Windows or web applications?</rant>
To be honest, it's not as bad as it looks. Way back in April, 2006, the Microsoft .NET Compact Framework Team published atech note with samples showing how to customize the DataGrid control, adding such field types as editable, formatted text, checkbox, pulldown lists, a date picker, and an up/down control. Unfortunately there's very little documentation with the sample.

C# code
The
SetupTableStyles
function must be called in the form's Load
event handler rather than the constructor since the data and screen need to be initialized before it will work.
It would be nice to add designer support so the custom grid can be initialized directly from the screen builder. As always, adding designer support to compact framework controls is needlessly painful, but I'll try ...
private void SetupTableStyles() { Color alternatingColor = SystemColors.ControlDark; DataTable vehicle = dataSource.Tables[1]; // ID Column DataGridCustomTextBoxColumn dataGridCustomColumn0 = new DataGridCustomTextBoxColumn(); dataGridCustomColumn0.Owner = this.dataGrid1; dataGridCustomColumn0.Format = "0##"; dataGridCustomColumn0.FormatInfo = null; dataGridCustomColumn0.HeaderText = vehicle.Columns[0].ColumnName; dataGridCustomColumn0.MappingName = vehicle.Columns[0].ColumnName; dataGridCustomColumn0.Width = dataGrid1.Width * 10 / 100; // 10% of grid size dataGridCustomColumn0.AlternatingBackColor = alternatingColor; dataGridCustomColumn0.ReadOnly = true; dataGridTableStyle1.GridColumnStyles.Add(dataGridCustomColumn0); // Make column DataGridCustomTextBoxColumn dataGridCustomColumn1 = new DataGridCustomTextBoxColumn(); dataGridCustomColumn1.Owner = this.dataGrid1; dataGridCustomColumn1.HeaderText = vehicle.Columns[1].ColumnName; dataGridCustomColumn1.MappingName = vehicle.Columns[1].ColumnName; dataGridCustomColumn1.NullText = "-Probably Ford-"; dataGridCustomColumn1.Width = dataGrid1.Width * 40 / 100; // 40% of grid size dataGridCustomColumn1.Alignment = HorizontalAlignment.Right; dataGridCustomColumn1.AlternatingBackColor = alternatingColor; dataGridTableStyle1.GridColumnStyles.Add(dataGridCustomColumn1); // Mileage column DataGridCustomUpDownColumn dataGridCustomColumn2 = new DataGridCustomUpDownColumn(); dataGridCustomColumn2.Owner = this.dataGrid1; dataGridCustomColumn2.HeaderText = vehicle.Columns[2].ColumnName; dataGridCustomColumn2.MappingName = vehicle.Columns[2].ColumnName; dataGridCustomColumn2.NullText = "-Unknown-"; dataGridCustomColumn2.Width = dataGrid1.Width * 20 / 100; // 20% of grid size dataGridCustomColumn2.Alignment = HorizontalAlignment.Left; dataGridCustomColumn2.AlternatingBackColor = alternatingColor; dataGridTableStyle1.GridColumnStyles.Add(dataGridCustomColumn2); // Availability column DataGridCustomCheckBoxColumn dataGridCustomColumn3 = new DataGridCustomCheckBoxColumn(); dataGridCustomColumn3.Owner = this.dataGrid1; dataGridCustomColumn3.HeaderText = vehicle.Columns[3].ColumnName; dataGridCustomColumn3.MappingName = vehicle.Columns[3].ColumnName; dataGridCustomColumn3.NullText = "-Unknown-"; dataGridCustomColumn3.Width = dataGrid1.Width * 10 / 100; // 10% of grid size dataGridCustomColumn3.Alignment = HorizontalAlignment.Left; dataGridCustomColumn3.AlternatingBackColor = alternatingColor; dataGridTableStyle1.GridColumnStyles.Add(dataGridCustomColumn3); // Fuel Level column DataGridCustomComboBoxColumn dataGridCustomColumn4 = new DataGridCustomComboBoxColumn(); dataGridCustomColumn4.Owner = this.dataGrid1; dataGridCustomColumn4.HeaderText = vehicle.Columns[4].ColumnName; dataGridCustomColumn4.MappingName = vehicle.Columns[4].ColumnName; dataGridCustomColumn4.NullText = "-Unknown-"; dataGridCustomColumn4.Width = dataGrid1.Width * 30 / 100; // 30% of grid size dataGridCustomColumn4.Alignment = HorizontalAlignment.Left; dataGridCustomColumn4.AlternatingBackColor = alternatingColor; dataGridTableStyle1.GridColumnStyles.Add(dataGridCustomColumn4); // Last Used column DataGridCustomDateTimePickerColumn dataGridCustomColumn5 = new DataGridCustomDateTimePickerColumn(); dataGridCustomColumn5.Owner = this.dataGrid1; dataGridCustomColumn5.HeaderText = vehicle.Columns[5].ColumnName; dataGridCustomColumn5.MappingName = vehicle.Columns[5].ColumnName; dataGridCustomColumn5.NullText = "-Unknown-"; dataGridCustomColumn5.Width = dataGrid1.Width * 30 / 100; // 30% of grid size dataGridCustomColumn5.Alignment = HorizontalAlignment.Left; dataGridCustomColumn5.AlternatingBackColor = alternatingColor; dataGridTableStyle1.GridColumnStyles.Add(dataGridCustomColumn5); // Grid, mapping dataGridTableStyle1.MappingName = vehicle.TableName; // Setup table mapping name dataGrid1.DataSource = vehicle; // Setup grid's data source ComboBox cb = (ComboBox)dataGridCustomColumn4.HostedControl; DataTable fuel = dataSource.Tables[0]; // Set up data source cb.DataSource = fuel; // For combo box column cb.DisplayMember = fuel.Columns[0].ColumnName; cb.ValueMember = fuel.Columns[0].ColumnName; dataGrid1.CurrentRowIndex = 50; // Move to the middle of the table }
Code notes
Note the funky cast when setting up the combo box's data source. This is because the
HostedControl
is exposed as the base Control
class.ComboBox cb = (ComboBox)dataGridCustomColumn4.HostedControl;
How did they do that?
The Compact Framework 2.0 Service Pack 1 introduced the following extensions to provide better data formatting and custom cell drawing:
- DataGridColumnStyle
- PropertyDescriptor descriptor allows access to this column data in the data source so it could be processed as needed.
- Paint() method is called as cell is drawn. Overriding it allows representing data from data source in any way imaginable. Colors, fonts, formatting, alignment, pictures and more - anything is possible as long as it can be painted. CurrencyManager and row number along with PropertyDescriptor allows fetching data from data source to convert and format the way you want.
- DataGridTextBoxColumn
- Format string to be used to format data in the column. To be used the same way as on desktop or in simple data binding.
- IFormatProvider FormatInfo Format provider to be used to format data in the column. To be used the same way as on desktop or in simple data binding.
Links
- .Net Compact Framework V2 Service Pack 1 Data Grid control enhancements
- DataGrid with a custom header and selection
- Exposing hidden properties in Compact Framework Datagrid through reflection - see article for complete list of properties available
- Working with the DataGrid Control
- Using the DataGrid in the .NET Compact Framework (MSDN)