Building Nested Grids
A hierarchical DataGrid control makes sense only if the data source is a DataSet object that contains relations between tables. For example, consider a DataSet with Customers and Orders tables with a DataRelation set between the two on the CustomerID column. As long as the DataGrid contains a button column, when you click it you could create a child view for the selected customer and bind the resulting DataView object to the child grid.
Because the new control (named NestedGrid in the sample code) inherits from the DataGrid class, you can use it whenever a DataGrid object is appropriate. However, take this last statement with a grain of salt. In general, when you derive a control from a base class there might be situations in which the derived control can't just replace the original due to its specific extensions and additions. In this column, I won't spend much time making the NestedGrid component backward compatible with the base DataGrid class. For simplicity, I'll assume that you always bind it to a DataSet object.
I make a few more assumptions regarding the NestedGrid control, which will become clear later on. In particular, you are responsible for adding a button column that will dictate the expanded/collapsed state of each row. In theory, this column can be placed anywhere in the grid. However, I assume here that the expand column is the first column in the grid. (As discussed in the August 2003 issue, you could modify the behavior to dynamically generate the column only if the DataGrid is bound to a DataSet that has related tables.)
If you've played with the DataGrid control a bit, you know that although it's extremely powerful and customizable, it doesn't happily support changes in its layout. The layout of a grid represents a table of data—a regular succession of equally sized rows. How can you embed a child grid with this restriction?
The key point to recall here is that the grid is rendered as a standard HTML table. Once the cells form a regular table layout, you can place anything within each of them, including a child table that represents a child grid (using a rowspan tag). First, you modify the number of cells that form the selected row—that is, the row where the expand command button that the user clicked is located—by removing all the cells except the one that contains the command button. This is pretty easy to do if you assume that the expand command column is the leftmost one. Once all the cells have been removed, then you can create a brand new one that spans the necessary number of columns, equal to the number of items in the Columns collection of the DataGrid control.
At this point, you have a completely custom cell for the row to expand. This custom cell can be programmatically populated with any combination of server controls. For example, you can insert a table in which the top row mimics the structure of the removed cells (typically, information about the parent row) and the bottom row contains the child DataGrid. The control in Figure 2 is created based on this scheme.
"If you share your assets (money etc..) it will decrease, But if you share your knowledge it will increase!!! ".