How Grids Connect to Data
Let's look at what's needed to connect the grids to the related data.
grid.DataSource = m_data
grid.DataMember = "Employees"
gridOrders.DataSource = m_data
gridOrders.DataMember = "Employees.Emp2Ord"
Both grids are bound to the same DataSet which contains both Employees and Orders tables. The parent grid is bound to the parent tableEmployees. The child grid is bound to the dynamically changing table resulting from the Emp2Ord
relation applied to the Employees table. As a result, when a new row is selected on the parent grid, the child automatically detects the movement, retrieves the new subset of rows, and refreshes itself.
All this works for free but doesn't give any chance to get into the game; you can't even grab the key field of the selected row. To access the row yourself, you must take the binding context route.
What strikes me most about this feature is that the two grids are not related in any way. The child grid doesn't know which control acts as the parent; the parent ignores if and where a child grid exists. Explaining the underpinnings of this mechanism (no black magic, just smart code) is beyond this article. I wrote an article for MSDN Magazine
about this that you can access here
I'll only say that the binding context plays a key role. In practice, if the grid control detects that its DataMember
property has the form of Table.Relation
, then it connects to the form's binding context asking for the manager of its DataSource
and the table name in the DataMember
. Next, it registers to handle the CurrentChanged
event on the binding manager. This way the grid is notified whenever a control bound to that source changes its current element. At this point, the grid realizes it's been configured to be the child of a relation. It extracts the Relation part from the DataMember
property and using plain ADO.NET code retrieves the subset of rows to display. Guessed the final step already? The content of the grid is cleared and refreshed!
Present and Future of Windows Forms
If you want to customize the look-and-feel of the Windows Forms DataGrid control beyond the threshold discussed here, consider that the complexity of the code required grows exponentially. To define a new column type, for example, you just have to add concrete code to a bunch of abstract methods on the DataGridColumnStyle
class; you also have to figure out how to do that. No samples are provided but a clear message surfaces from the MSDN documentation. The underlying mechanism of Windows Forms is still the Win32 owner-draw modela feature that I hope to see changed in .NET. (See Sidebar: Owner-draw Model
) The CreateWindowEx
API is still key to Windows Forms and Microsoft didn't put much effort into creating an abstraction layer to let us use and embed .NET controls in the UI of controls.
Windows Forms give you great features but leaves a lot of unfilled gaps here and there. Professional looking and feature-rich grids often require you to do without the DataGrid and be designed from scratch. So much for the present, but what's the future?
The future of Windows Forms is something called Longhorn and it is expected to ship sometime around 2004. Longhorn will be the first version of Windows that features completely managed code. By then the Win32 API will be gone forever. Microsoft is working on a new user interface API (codenamed Avalon) to be used in the Windows shell as well as in the next generation of desktop applications. Putting more effort in the Windows Forms of today is a lost investment. That's why they come up with some great features and some gaps as well. Not too great; not too bad. Stay tuned.