Winforms ComboBox 2 way databinding only works 1 way - winforms

I have a combobox, and in the design view I have it databound to a bindingsource as follows:
this.itemTypeComboBox.DataBindings.Add(new System.Windows.Forms.Binding("SelectedValue", this.itemTypeContainerBindingSource, "ItemType", true));
this.itemTypeComboBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.itemTypeContainerBindingSource, "ItemType", true));
In the code behind in the load event I have the following:
// bind the combobox to the enum
this.itemTypeComboBox.DataSource = Enum.GetValues(typeof(OpticalItemType));
// bind a custom object to the datasource
this.itemTypeContainerBindingSource.DataSource = customObjectContainer;
The "customObjectContainer" is a single object that contains a property "ItemType" that is bound to the combobox, and all properties of the object use change notification through "INotifyPropertyChanged".
In my code behind, if I programmatically change the custom object, the changes are reflected in the combobox. However, if I change the combobox through the UI, the bindingsource, and hence the custom object do not reflect the changes.
Any ideas what I am doing wrong?
As it is a singular object, it cannot be to do with using BindingList etc.
UPDATE 1:
Ok, whenever I change the combobox through the UI, it never changes the underlying object, the setter is never hit for the property in the custom object. However, I have just noticed that if I tab off of the control, it then fires the setter, and changes the underlying object. Why would this be?
PROBLEM SOLVED:
It appears, the issue was with my binding. I added "DataSourceUpdateMode.OnPropertyChanged" to the bindings, and it works now!!

The issue was with my binding. I added "DataSourceUpdateMode.OnPropertyChanged" to the bindings, and it works now!!

Related

Control.DataBindings.Add in WinForms

When a data binding is added to a control in WinForms:
Binding b =new Binding("Text", myDataRowView, "title");
TitleTextBox.DataBindings.Add(b);
the textbox displays the value at myDataRowView["title"].
If myDataRowView["title"] is then updated (directly, not via the form control) so that its value changes
myDataRowView["title"] = "foo";
is the textbox supposed to reflect the new value? Does Adding the binding to the textbox set up a listener to listen for changes to the column to which it has been bound?
Or does the control have to be rebound to the DataRowView whenever the DRV is changed in code, i.e. not as the result of user typing data into the form control?
When we say updation - there are two scenarios here.
Update the underlying datasource connected to the control (textbox in your case). For that look at the add overload - Add Method (String, Object, String, Boolean, DataSourceUpdateMode) The DataSourceUpdateMode property controls how the update happens.
OnValidation - If you have some validation rules for your control, underlying value won't be updated if validation fails.
OnPropertyChanged will update underlying source in any case.
Update the control when the datasource is updated.
The INotifyPropertyChanged interface is used to notify clients, typically binding clients, that a property value has changed. So for this you need to implement this interface.

When binding to a combobox SelectedItem the change is only notified on lost focus. How to notify when selection is changed?

I've bound it using
cmbPeriod.DataBindings.Add("SelectedItem", Presenter, "SelectedDate", true, DataSourceUpdateMode.OnPropertyChanged);
But it only fires to the bound model when I tab out of the control, I'd like it to fire the moment the users makes a new selection.
EDIT: Ok so I tried binding using SelectedValue instead and leaving the ValueMember as null. This had the effect of updating the source as soon as the combobox changes with the correct object, however now the combobox ignores updates from the source!!
I see it requesting the binding at runtime and my source property returns the correct object, which is the the same type the combobox will update the source with on change. Ugh! So close:(
cmbPeriod.DataBindings.Add("SelectedValue", Presenter, "SelectedDate", true, DataSourceUpdateMode.OnPropertyChanged);
binding to SelectedValue works on change

"Nested" MVVM Question

I have a WPF window that has a datagrid and a user control for a form for the fields in that datagrid. The user control and the WPF window have view models.
The user control's DataContext is bound to one of the window's view model's member field, whose value changes during the data grid's Selection Changed event.
I'm not sure if this is the right way to do it because I am unable to create references from the inner view model to the outer view model for some reason. Constructor injection won't work because I'm required to use default constructor only, and I can't seem to put a property injector in the right place (always getting null reference when I try to use it).
I am also unable to get my property change notification to work properly in the inner view model.
Is there a better way to wire my view models so that they automatically change the values in the user control when a new row is selected in the datagrid? I have a feeling that binding to the control's DataContext is not the way to go.
This doesn't seems a complex/nested scenario. Looks like pretty much a normal master details scenario. Suppose you want to edit Customer data, I would have an ObservableCollection instance bind to the DataGrid, and there will be a SelectedCustomer property in the VM also. In the DataGrid you can set SelectedItem twoway bind to the SelectedCustomer property which makes SelectedCustomer always updated with your selection. Since the usercontrol has the same instance of customer as in the DataGrid row, whenever you change anything in the UC those data will get reflected in the grid. Ofcourse all those properties should fire NotifypropertyChanged.

Checkboxes not updating as expected

I have a listbox bound to a list of business objects. The items in the listbox are formatted using an itemtemplate. The itemtemplate includes a checkbox bound to a boolean property of the business object. When I spin up the app, the bool prop on the object in the list is changed when I click the checkbox. so far, so good.
The dialog has "select all" and "clear all" buttons. When I click on of these buttons, the properties on the objects are changed but the checkbox does not update.
The code in the select all click event is. . .
For Each x As BusObj In _BusObjList
x.BlockIsInserted = True
Next
I can step through the code and watch the object properties change but the checkbox does not update. Any suggestions?
Thanks,
using twoway binding should help I guess
{Binding ..., Path=Text, Mode=TwoWay}
And yes, is BlockIsInserted property dependency? or implemented INotifyPropertyChanged?
I've encountered the same issue, even with the binding set to two-way and the view model representing the business object correctly implementing INotifyPropertyChanged. The (rather brute-force) solution I found was to NotifyChanged on the property representing the collection of business objects - this fixes the problem.

BindableAttribute, Combobox, Selectedvalue property - WinForms

I am deriving from combobox (WinForms) and am providing a new implementation for the Selectedvalue property.
It works fine as is, but any change to the selectedvalue property is not updating other controls bound to the same "binding context" to change their values accordingly.
I did try adding the BindableAttribute(true) to the property, but still it does nottrigger the change in value to the other linked controls.
The control's DataBindings.add(...) is all set up. And other controls are also bound to the same data filed on the same datasource.
Any ideas what i am doing wrong.
Have you called your base class' implementation of overridden methods? It's possible that failing to call the base class implementation is accidentally circumventing the code that fires various event plumbing.

Resources