views:

442

answers:

3

The following code works as you’d expect — MyProperty on the model is updated when the user picks a new item in the dropdown.

comboBox1.DataBindings.Add("SelectedValue", myModel, "MyProperty", true,
DataSourceUpdateMode.OnPropertyChanged);

The following, however, doesn’t work the same way and the model update isn’t triggered until the input focus moves to another control on the form:

comboBox1.DataBindings.Add("SelectedItem", myModel, "MyProperty", true, 
DataSourceUpdateMode.OnPropertyChanged);

Does anybody know why? I don’t even know where to start investigating the cause. Pointers in the right direction to start the investigation or an outright explanation would be equally appreciated. Thanks.

Edit: for my purposes, I ended up binding to both SelectedItem and SelectedValue. This way I get instant model updates based on UI changes (through SelectedValue binding), and UI updates based on programmatic model changes (through the SelectedItem binding).

A: 

This is a long-standing "feature" of the list controls in .NET in my experience. Personally, I would just bind to the on change of the SelectedValue property and write whatever additional code is necessary to workaround this "feature" (such as having two properties, binding to one for SelectedValue, and then, on the set of that property, updating the value from SelectedItem in your custom code).

Anyway, I hope that helps =D

Allen E. Scharfenberg
I ended up setting up two bindings -- one to SelectedValue and one to SelectedItem and didn't need any custom code beyond that. :)
Anna Lear
@Anna Glad to hear that you got it working :)
Allen E. Scharfenberg
+1  A: 

I suspect that the SelectedItem property of the ComboBox does not change until the control has been validated (which occurs when the control loses focus), whereas the SelectedValue property changes whenever the user selects an item.

Here is a reference to the focus events that occur on controls:

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validated.aspx

George Howarth
A better answer than mine. It is also important to point out that you will not be able to use SelectedItem when bound to SelectedValue because it will not be updated yet. If I remember correctly, you have to use retrieve from the Items collection of the list control by SelectedIndex.
Allen E. Scharfenberg
Thanks, George.
Anna Lear
+3  A: 

The ComboBox control inherits from the ListControl control.

The SelectedItem property is a proper member of the ComboBox control. The event that is fired on change is ComboBox.SelectionChangeCommitted

ComboBox.SelectionChangeCommitted

Occurs when the selected item has changed and that change is displayed in the ComboBox.

The SelectedValue property is inherited from the ListControl control. As such, this property will fire the ListControl.SelectedValueChanged event.

ListControl.SelectedValueChanged

Occurs when the SelectedValue property changes.

That said, they won't fire the INotifyPropertyChanged.PropertyChanged event the same, but they will anyway. The only difference is in the firing event. SelectedValueChanged is fired as soon as a new selection is made from the list part of the ComboBox, and SelectedItemChanged is fired when the item is displayed in the TextBox portion of the ComboBox.

In short, they both represent something in the list part of the ComboBox. So, when binding either property, the result is the same, since the PropertyChanged event is fired in either case. And since they both represent an element from the list, the they are probably treated the same.

Does this help?

EDIT #1

Assuming that the list part of the ComboBox represents a property (as I can't confirm since I didn't write the control), binding either of SelectedItem or SelectedValue affects the same collection inside the control. Then, when this property is changed, the same occurs in the end. The INotifyPropertryPropertyChanged.PropertyChanged event is fired on the same property.

Will Marcouiller
Yes, I think that helps. Thanks!
Anna Lear
Thanks for feedback. I edited my answer to push it a tiny further.
Will Marcouiller