Browse DevX
Sign up for e-mail newsletters from DevX


Customize the Windows Forms DataGrid Control : Page 4

The System.Windows.Forms.DataGrid control is an Excel-like component and designed to display data contained in .NET collections and list objects, including ADO.NET DataTable and DataView objects and arrays. The control provides scrolling capabilities, both vertically and horizontally, column resize, in-place editing, sorting, and even navigation, should your data source contain hierarchical information.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Accessing the Selected Row
If you use a DataGrid control, chances are good that you need to implement some sort of drill-down mechanism on top of a parent/child table relationship. To illustrate this, suppose that you want users to click on the parent grid to select an employee name and see all the orders he or she managed in a timeframe. When it comes to this there's good and bad news.

The bad news is that the DataGrid provides no ready-to-use way to get the data object behind the currently selected row. The good news (great, indeed) is that in most cases you don't need to take care of that because the DataGrid has the ability to automatically set up master/details relationships.

Suppose that you want to update the caption of a child control to reflect the last name of the currently selected employee. To do this you must cache a reference to the form's so-called binding context. The binding context for a Windows Forms form is a collection called BindingContext that tracks all links between controls and bound data containers. You must obtain the binding manager for all controls bound to the specified data source. The returned object is of type BindingManagerBase.

Sub SetBindingContext() m_bindingContext = Me.BindingContext( _ m_data, "Employees") ' *** more code here End Sub

You declare a member of type BindingManagerBase with the WithEvents qualifier and define a handler for its CurrentChanged event.

Sub m_bindingContext_CurrentChanged( _ ByVal sender As Object, _ ByVal e As EventArgs) _ Handles m_bindingContext.CurrentChanged Dim row As DataRow Row = CType(m_bindingContext.Current(), _ DataRowView).Row : End Sub

Cast the object returned by the binding context's Current property to DataRowView and you finally get the reference to the currently selected row.

Scared by this code? Consider that if you don't need to directly manipulate (i.e., to refresh helper controls) the contents of the selected data row, you can rely on the auto-refresh capability of the DataGrid control. You define a relation between tables in the DataSet and let the parent and child grids know about that. Magically, the two grids synchronize in a rather codeless way.

For example, add two tables to the DataSet—Employees and Orders—and define the following relation on the common employeeid column. The Orders table contains orders issued by a given employee.

Dim t1 As DataTable t1 = m_data.Tables("Employees") Dim t2 As DataTable t2 = m_data.Tables("Orders") Dim dc1, dc2 As DataColumn dc1 = t1.Columns("employeeid") dc2 = t2.Columns("employeeid") Dim relEmpToOrders As DataRelation relEmpToOrders = New DataRelation("Emp2Ord", _ dc1, dc2) m_data.Relations.Add(relEmpToOrders) ' Add an extra column t1.Columns.Add("OrdersPerEmp", _ GetType(Integer), _ "count(child(Emp2Ord).employeeid)")

Figure 3: Synchronized grids in action. The child grid is mapped to the subset of rows in the parent grid that results from the relationship.
The code above defines a DataRelation object between the two tables in the same DataSet. The relation makes it easy to retrieve all the orders for a given employee. It is so easy that you could also add an expression-based column to the Employees table to cache how many orders each employee issued. The expression counts the distinct employeeid values according to the defined relationship.

Believe it or not, this code produces the output in Figure 3. The two grids are synchronized without the need to write specific code.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date