Master detail combo boxes in windows forms

An application I was working on today required two comboboxes to be linked as parent and child (master and slave). Changing the selection on the first combobox needed to cause the second box to provide choices from a child table. For example, the first box could be a list of country codes and the second box could be a list of states or provinces within the country.

It had been a while since I had done winforms development but the .net environment gives great support for this kind of shared state through the binding manager and so I was expecting it to be easy - set the datasource and then the display member and we're done. Oh right, I then remembered that I would have to use the relationship between the parent and child tables to control the slave combobox. Then I got stuck on what to set in the the datasource and display member properties. The last time I did this I think I used datagrids and that was what I thought of trying first. For a datagrid, the answer looks something like this:

datagrid1.DataSource = ds;

datagrid1.DataMember = ds.Relations["parent_child"];

Where parent_child is the name of the relation between the two tables. But there is no DataMember property on the combobox and, come to think of it, how would the combobox know what column I wanted? So after some experiments and some searching around the web I found what I needed to make it work in Dino Esposito's article: http://www.devx.com/codemag/Article/22028/1954?pf=true. I tried setting the DataSource to the data set and the DisplayMember to the path of the column on the child like this:

combobox2.DataSource = ds;

comboBox2.DisplayMember = "parent.parent_child.childCol1";

This nearly worked, the second combobox now displayed data from the child table but it did not change when I changed the parent. Here is what the parent looked like:

combobox1.DataSource = ds.Tables["parent"];

combobox1.DisplayMember = "parentCol1";

The problem was that the binding context set up a different manager for the two controls because their datasources were different. By changing the parent to:

combobox1.DataSource = ds;

combobox1.DisplayMember = "parent.parentCol1";

Now they shared the same binding manager and the controls worked as required.

Hope this saves you some time.

Comments

  • andre February 8, 2005 8:35 AM

    Thank you very much.

  • andre March 7, 2005 8:52 AM

    Private Sub frmCmbRelation_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    cn = New SqlConnection("server=xyz;database=abc;user=abc;pwd=acc;")
    cn.Open()
    dabank.SelectCommand = New SqlCommand("select * from vw_bankmast", cn)
    dabank.Fill(ds, "vw_bankmast")

    dabranch.SelectCommand = New SqlCommand("select * from vw_bankbranch", cn)
    dabranch.Fill(ds, "vw_bankbranch")

    drbankbranch = New DataRelation("drbb", ds.Tables(0).Columns(0), ds.Tables(1).Columns(1))

    cmbBank.DataSource = ds
    cmbBank.DisplayMember = "VW_BANKMAST.BK_ID"

    cmbBranch.DataSource = ds
    cmbBranch.DisplayMember = "VW_BANKMAST.drbankbranch.bb_bkid"

    I m having problem with this code..
    i want bank name in cmb_bank
    and childs of tht bank means branches in other
    combo named cmb_branch..
    but having problem.
    code not work
    and display "ystem.Data.
    DataViewManagerListItemTypeDescriptor"
    in child combo,,
    pls reply..
    thanks in advance

  • andre March 9, 2005 9:46 PM

    Hi Bhavesh
    You almost have it. Use the same name in the slave combo box as you did in the construction of the relation: drbb
    So your second box would be:
    cmbBranch.DisplayMember = "vw_bankmast.drbb.bb_bkid"
    be careful with the names, they are case-sensitive.
    good luck,
    a

  • andre March 10, 2005 4:08 AM

    Hi Andre,
    thanks very very much..
    the code works now..
    now i want to talk about second problem.
    I create master-detail datagrid.
    and also i got sucess, but way it looks is so
    poor.
    Its not user-friendly thats what I think.
    so is there other way to change it display.which looks good.
    reply soon.
    thanks once again.

  • andre March 10, 2005 4:11 AM

    i have problem that the mdi child form's main menu appends to the mdimain form's mainmenu.

    i like to mdi child's main menu must stay with the mdi child form.

    can anybody help me?
    what i should do?
    thnks...

  • andre May 24, 2005 2:39 PM

    Great!!!
    Thanks a lot, it's a good job.

  • andre June 10, 2005 1:05 PM

    I'm wondering how to do Master/Detail relationship using ComboBoxes. I'm
    using VB (2003).


    I have DataSet containing tables called as 'State' and 'City' (not really
    'State' and 'City' but idea is the same and easier to understand). I want
    user to select first 'State' of the ComboBox containing states and then the
    ComboBox containing cities should contain only cities for that selected
    state. I want to save only ID (.ValueMember) of the state and city to the
    database table. How to do this when using DataBinding?, I can;t understand you code because I don't know where comming prom "Parent", also I was wondering if you can do it with my code to see a more specific sample.


    At the moment code looks like this ...


    '// *** 'State' ComboBox ***
    cbState.DataSource = ds.Tables("States")
    cbState.DisplayMember = "State"
    cbState.ValueMember = "ID"
    cbState.DataBindings.Add(New Binding("SelectedValue", myDataTable,
    "StateID"))


    '// *** 'City' ComboBox ***
    cbCity.DataSource = ds.Tables("Cities")
    cbCity.DisplayMember = "City"
    cbCity.ValueMember = "ID"
    cbCity.DataBindings.Add(New Binding("SelectedValue", myDataTable, "CityID"))


    ... and it's working fine, but I need to implement this selection
    relationship somehow.

    Regards
    Carlos Vara

  • andre July 14, 2005 12:12 AM

    what a load! just an add for devx, don't waster your time. (if youdon't believe me try and explore the rest of this site).

Anonymous comments are disabled