views:

2307

answers:

2

Hi,

I am trying to implement the following: Two combo boxes on a Winforms form, the first has a list of parent categories, the second is children of the parent, the child list changes contents depending on the selection in the parent.

I'm trying to do this properly using databinding but I'm finding a strange quirk with the ComboBox control.

I set the datasource of the parent manually:

cboParent.DataSource = ParentDataSource where ParentDataSource is IList<ParentDTO>. I can then bind the seletedItem to the DTO thus:

cboParent.DataBindings.Add(new Binding("SelectedItem", bindingSource, "Parent", true, DataSourceUpdateMode.OnPropertyChanged)); binding to Parent a ParentDTO object on my overarching DTO.

All pretty standard so far. This works and writes back the change to my DTO object as soon as I select anything new in the list, great!

I then bind the child combo box datasource to a list in the overarching DTO: cboChild.DataBindings.Add(new Binding("DataSource", bindingSource, "Children", true, DataSourceUpdateMode.OnPropertyChanged)); where Children is an IList<ChildDTO> on the overarching DTO.

This also works fine and as soon as I change the parent selection the presenter changes the list Children on the DTO and the values shown in cboChildren changes, fantastic I hear you cry (and I did myself)!

Unfortunately it seems that if you're using databinding to set the datasource on a ComboBox the SelectedItemChanged, SelectedIndexChanged and SelectedValueChanged events don't fire at all, ever! This means that OnProperyChanged databinding won't work for the second combobox. OnValidation does work but it seems a little odd to me and I was wondering if anyone had encountered this before and if they'd worked out how to make it work?

Thanks in advance

Stu

A: 

well still need help? you need to create bindingSources and a aux textbox for a filter and use the handy property bindingSource.filter

Here is how:

Dim ds As New DataSet
Dim bind1 As New BindingSource
Dim bind2 As New BindingSource

'' here I add data to the dataset.. you MUST do your own populate way
ds.Merge(GetProducts) ' returns a dataset filled with products
ds.Merge(GetCategories) ' returns a dataset filled with categories

'' after the ds has data

    ' create binds 
    bind1.DataSource = ds
    bind1.DataMember = "products"

    ' crete binds
    bind2.DataSource = ds
    bind2.DataMember = "categories"

    txtMaster.DataSource = bind1
    txtMaster.DisplayMember = "product_name"
    txtMaster.ValueMember = "product_id"

    txtDetails.DataSource = bind2
    txtDetails.DisplayMember = "category_name"
    txtDetails.ValueMember = "category_id"

    txtAux.DataBindings.Add("Text", bind1, "product_id") ' bind1 contais products data

' this perform a filter on bind2... that contains categories data Private Sub txtMaster_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMaster.SelectedIndexChanged bind2.Filter = "product_id = '" & txtAux.Text & "'" End Sub

hope it help

A: 

Hi,

I have derived the ComboBox for a few reasons, for example to support binding to null DTO's. This helped me to insert this functinulity to fix the problem that Binding is not updated:

public new object SelectedItem { get { return base.SelectedItem; } set { base.SelectedItem = value; if (value == null || value == System.DBNull.Value) { this.SelectedIndex = -1; } foreach (Binding binding in DataBindings) { if (binding.PropertyName == "SelectedItem") { binding.WriteValue(); } } } }

You may want to do so also if property name is SelectedValue or selectedIndex.

If this helped someone please post back!

Best Regards, Efy