For me, the pain and pleasure of programming with C# and .NET can be best represented by the default DataGrid control for Windows Form. On it’s face the DataGrid control is functional, useful and performs well. A data source can easily be bound to the control and the fields represented in the control can easily be updated by simply updating a field in the underlying dataset, reflection takes care of the rest.
As long as you only want to place text in the DataGrid control, you need go no further. But when is that really the case? Many times in a form, the DataGrid will need to represent other values or host other types of controls, and it is obvious that this was known to be true when the control was created because the default DataGrid control actually presents two types of other controls within its matrix, the TextBox control and the CheckBox control.
Here’s how it works. The DataGrid presents data in its matrix based on the table and column styles applied to it. Let’s say we have a table queried from a SQL Server and that table contains a number of rows and each row has three fields, one Boolean field and two text fields (in that order). If you did not care about the presentation of these fields you could just leave them all as the default TextBox control and each value in each field would be presented and raw text. But clearly it would be better to show the Boolean field as something more appropriate, like a CheckBox for instance. First you would create your DataGrid object and your DataSet or DataTable object. Next you would want to create a DataGridTableStyle object to hold a series of column style objects. With the default DataGrid you are only given two choices, a DataGridTextBoxColumn style object and a DataGridBoolColumn style object. Each of these style objects contain a number of properties including things such as column width, formatting, and read only properties. Once these column style objects are added to the DataGridTableStyle object, the DataGridTableStyle object can be linked to the DataGrid object and the values of the DataTable (or DataSet) will be presented in the visual styles you have designated. In the case of our example, the Boolean column would look like a CheckBox object and the text columns would look like TextBox objects.
This seems like a long way to go just to add some simple formatting options to a DataGrid. Worse yet, this is a long way to go just for two simple presentation types. But this is where .NET turns this extra work into something powerful.
Let’s try a new example. Say we have a new DataTable object that contains a Boolean field, an Image (containing an Icon) field and a Text field. As I’ve shown, displaying the Boolean and Text fields is easily done, even if tediously so. But now we want the DataGrid object to show the actual Image in the second column. Putting the power of .NET to work, we create a new column style class by first deriving from an existing class, the DataGridTextBoxColumn class. We’ll call the new class DataGridImageColumn. Now we simply need to override the Paint method of our new class and alter it to draw the image found in the table for this row. Graphics.DrawImage does the trick and now we can assign our new column style to the DataGridTableStyle object and apply the DataGridTableStyle object to the DataGrid object.
And that is the heart of .NET. Sure the wizards who made the default DataGrid control could have added a few more column styles for obvious choices like Images. After all, if a monkey like me and figure it out it wouldn’t be a problem for them. But that is not what .NET is all about. .Net is about empowering the developer with everything they need to do what they need. Why should someone in Redmond tell you what your application can and cannot do? Why add a bunch of extra crud that you may have to work around just to get something you really want? No, it is far better to give you the tools to decide your own fate.