The class hierarchy for the main parts of the DataGridView control is shown in Figure 32-11.
The control uses objects derived from DataGridViewColumn when displaying data. As you can see from Figure 32-11, there are now far more options for displaying data than there were with the original DataGrid, One major omission was the display of drop-down columns with in the DataGrid – this functionality is now provided for the DataGridView in the form of the DataGridViewComboBoxColumn.
When you specify a data source for the DataGridView, by default it will construct columns for you automatically, These will be created based on the data types in the data source, so, for example, any Boolean field will be mapped to the DataGridViewCheckBoxCol umn. If you would rather handle the creation of columns yourself, you can set the AutoGenerateColumns property to false and construct the columns yourself.
The following example shows how to construct columns and includes an image and a Combo Box column. The code uses a DataSet and retrieves data into two data tables. The first DataTable contains the employee information from the Northwind database, The second table consists of the EmployeeID column and a generated Name column, which is used when rendering the Combo Box:
Here there are two things to note, The first select statement replaces null values in the Reports To column with the value zero. There is one row in the database that contains a null value in this field, indicating that the individual has no manager. However, when data binding, the comboBox needs a value in this column; otherwise, an exception will be raised when the grid is displayed, In the example, the value zero is chosen because it does not exist within the table – this is commonly termed a sentinel value because it has special meaning to the application.
The second SQL clause selects data for the Combo Box and includes a manufactured row where the values Zero and (None) are created. In Figure 32-12, the second row displays the (None) entry.
The custom columns are created by the following function:
The ComboBox is created last in this example – and uses the Managers table in the passed data set as its data source, This contains Name and EmployeeID columns, and these are assigned to the DisplayMember and ValueMember properties, respectively, These properties define where the data is coming from for the ComboBox.
The DataPropertyName is set to the column in the main ‘data table that the combo box links to – this provides the initial value for the column, and if the user chooses another entry from the combo box, this value is updated, The only other thing this example needs to do is handle null values correctly when updating the database. At present, it will attempt to write the value zero into any row if you choose the (None) item onscreen, This will cause an exception from SQLServer because this violates the foreign key constraint on the Reports to column.
To overcome this, you need to preprocess the data before sending it back to SQLServer, and set to null the ReportsTo column for any rows where this value was zero.