Databound combobox is no longer working as it should be. If you select an item and then tab or move away from the combobox the selection disappears.
Please try the attached sample.
The problem is caused by the order of the bindings. If you bind the list first and the selected value second it works fine.
this.ComboBox.DataBindings.Add(new Wisej.Web.Binding(“DataSource”, this.bindingSource1, “KnightsList”, true, Wisej.Web.DataSourceUpdateMode.OnPropertyChanged));
this.ComboBox.DataBindings.Add(new Wisej.Web.Binding(“SelectedValue”, this.bindingSource1, “KnightID”, true));
As it is now, you are binding the selected value first, so when you change the datasource and the bindings are refreshed, the selected value is updated first but the new key doesn’t exist in the list so it’s reset to the first. If you bind the list first, then the selected value will be found and it all works.
This is related to the “circular” binding, where the data source contains both the selected value and the lookup list.
I still have some issues with the databound ComboBox. Attached a modified sample.
The selection list in the ComboBox is right. But the selection does not work.
Click on “Get record 1”. “Mordered” is shown as selected that is right. Now, click on “Get record 2”. “Tannhauser” is selected. Wrong it should be “Vecelin”.
End execution and start the project again. This time click on “Get record 2” first. “Vecelin” is selected. Thats right. Now, click on “Get record 1”. “Uther” is shown as selected. It should be “Mordered”.
Uncommenting //ComboBox.DataSource = head1.KnightsList; and //ComboBox.DataSource = head2.KnightsList; in the code-behind seems to make it work. But it doesn’t make sense to me.
Following up on my comment.
If you want to avoid reloading the list when the instance changes you nee to bind to the specific property. The DataMember name is not a binding, it’s just the member to use to read the data. In your sample, do this:
This way you use a single binding source and the combobox data source is repopulated only when the specific member changes. You can also decide which event will cause the reloading of the list.
In the designer you can see all the bindings here:
Wisej binding (based on WinForms bindnig) is very flexible and powerful but it has probably too many options and settings.
The problem is that both datasources use the same object instance: BO.Head. They use different properties, but the same instance. When the combobox changes the “Number” property, the object fires PropertyChanged which tells the second binding list that it has changed, causing a reload of the data source: The same object instance is proving both the list source and the current item value.
It doesn’t matter that the DataMember is “KnightsList”, the entire data source is signaled as changed when BO.Number fires the PropertyChanged event. The DataMember is used only to pull the data since it can come from anywhere.
The only time that a single property change only affects the binding to that specific property is when using DataBindings on specific properties.
There is really no way around this other than:
1) Don’t fire PropertyChanged, or
2) Better to split the record item from the list source like you did now. You can assign it in the same place where you currently assign the data source to bindingSource1, it doesn’t have to be in the designer.
Thanks for explaining and a working solution.
I have changed the test code to:
knightsListBindingSource.DataSource = head.KnightsList;
bindingSource1.DataSource = head;
If you have a lot of Comboboxes you have to set the datasource for each of them in the code behind every time you change the main datasource. Not as nice/clean as just wire it up in the UI designer.
The list bindingsource should only refresh when the DataMember property changed. How about adding a new behavior flag property on the bindingsource control that fix this?
Debugging issue WJ-8304 logged by Frank and thanks to your sample code I can see the problem and we can fix it to make it work also with the binding scenario in your test app.
However, the binding that you are using causes a circular update. You have 2 binding sources, one for the selected value (bindingSource1) and one for the list (knightsListBindingSource), which is OK. But the datasource for knightsListBindingSource is set to be bindingSource1, causing a circular update every time you change the value because your Head class fires INotifyPropertyChanges.PropertyChanged. So it tells the knightsListBindingSource that is has changed, which causes the bound combobox to reload the full list of items every time the value is changed.
If you try the same in WinForms you end up in a neverending validation loop and you can never leave the combobox.
The bug in Wisej is that it doesn’t update the client after the list has been reloaded a few times in the same cycle. The value on the server is correct, but the client doesn’t receive the update. The fix makes your sample work, but you still get a new full items list sent back to the client on each value change.
The correct way to bind knightsListBindingSource is to use the actual list as the data source.