Winforms Data Binding Lessons Learned

How to Make a Non-DataGrid Control Act as the Mast

This problem would occur whenever you want a control other than a DataGrid to serve as a master in a master-details, data-bound form. Imagine that the control that you have is a tree view. You fill up the treeNodes and set the node.Tag property with a DataRow object. You want the user to be able to click on a tree node and let a DataGrid on the form show the child rows of the selected data row.

If we have a ListBox or ComboBox control, this could be easy. You just set the BindingManager's position property to the current index of the control. But what about a tree view? The solution is pretty simple using a DataView object.

A DataView object has the ability to find a row based on a key and a value, meaning that if the DataRow is sorted according to the primary key of the table, you can use it to look up a row based on a given primary key. It contains a Find method, which returns the index to the row that was found. So, all you have to do is create a new DataView object, make it sort on your PK, and use it to find an index. Then you set the Binding manager's position according to the returned index. You need to bind your controls to that particular DataView, so you get the correct position. One word of caution: a DataTable object has by default a DefaultDataView property that you can use.

It is recommended to use a new DataView object, which gives you more flexibilty, and you can create 2 or even 10 different views of your data. You can sort them, filter them, or just show the rows that were last changed, added, deleted, or otherwise adapted. It's all there using the DataView.

Here's the code to handle the user selecting a tree node:

'Create a custom view of the data
Private view As New DataView(m_ds.Tables("Stuff"))
'make it sort based on the PK
view.Sort = "ID"


'Handling a listbox event
Private Sub listBox1_SelectedIndexChanged(sender As Object, e As System.EventArgs)
 
 
  'get the binding manager to set the position
  Dim bind As BindingManagerBase = BindingContext(m_ds, "Stuff")
 
  'Using the 'Find' of the DataView
  'returns the needed row index!
  'Just make sure you bind the ValueMember
  'property of the listbox
  bind.Position = view.Find(listBox1.SelectedValue)
End Sub 'listBox1_SelectedIndexChanged

'Handling a TreeView event
Private Sub treeView1_AfterSelect(sender As Object, e As System.Windows.Forms.TreeViewEventArgs)
  'get the binding manager to set the position
  Dim bind As BindingManagerBase = BindingContext(m_ds, "Stuff")
 
  Dim row As DataRow = CType(treeView1.SelectedItem.Tag, DataRow)
  Dim wantedID As Integer = Integer.Parse(row("ID").ToString())
  bind.Position = view.Find(wantedID)
End Sub 'treeView1_AfterSelect

You might also like...

Comments

About the author

Roy Osherove Israel

Roy Osherove has spent the past 6+ years developing data driven applications for various companies in Israel. He's acquired several MCP titles, written a number of articles on various .NET topic...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Some people, when confronted with a problem, think "I know, I’ll use regular expressions." Now they have two problems.” - Jamie Zawinski