1

I have a data object bound to a ComboBox, and when the selected value in that ComboBox is changed I'd like to update the data object and then refresh the datagrid the object is bound to.

The issue I'm encountering is that as far as I can tell, the event handler I've attached fires before the data object is updated and so when my data grid refreshes it still contains the old ComboBox value.

Here is my ComboBox control initialisation:

    cmbPaymentType.DataSource = _paymentTypes
    cmbPaymentType.DisplayMember = "PaymentTypeName"
    cmbPaymentType.DataBindings.Add("SelectedItem", _data, "PaymentType", False, DataSourceUpdateMode.OnPropertyChanged)

    cmbPaymentType.Refresh()

    AddHandler cmbPaymentType.DropDownClosed, AddressOf _data.NotifyDataChanged

When NotifyDataChanged is triggered, the data grid which uses my data object _data is refreshed, however the value of PaymentType is not updated. If I trigger NotifyDataChanged afterwards from elsewhere the data grid updates to the selected combo box value which indicates that the data object binding works, it's just being bound too late in my application flow.

How can I trigger an event after the data binding is updated?

Thanks!

Edit: the data object _data is an auto-generated Entity Framework class with a partial class I've written attached to it. If I were to use the INotifyPropertyChanged interface I do not know how to override the automatically generated properties to implement it correctly.

@Fabio's solution below solved my problem by manually updating the data binding when the combo box selection changed, meaning my event handling could take place afterwards and the data object would be updated before the data grid refreshed. I've rejigged his function slightly to work with the first data binding on any control:

Private Sub bindingUpdate(sender As Object, e As EventArgs)
    DirectCast(sender, Control).DataBindings(0).WriteValue()
    _data.NotifyDataChanged(sender, e)
End Sub
Charlie
  • 2,004
  • 6
  • 20
  • 40
Wibbler
  • 1,020
  • 9
  • 17
  • SelectedIndexChanged, Leave and various other events all have the same effect; they fire before the binding updates – Wibbler Jul 14 '15 at 07:43

2 Answers2

2

Your problem is binding to the SelectedItem.
As @Charlie was notice in the comments, property of the bounded item will be updated (in case of binding to SelectedItem) only after ComboBox looses a focus.

Because you want bind to the object, not to the property of the object, easiest way will be send message about updated value manually
Create handler for SelectionChangesCommitted event, which fires when SelectedItem is changed

Private Sub cmbPaymentType_SelectionChangesCommitted(sender As Object, e As EventArgs)
    DirectCast(sender, ComboBox).Bindings("SelectedItem").WriteValue()
    'Here you can update datagrid too
End Sub

Another approach is using DataBinding to the SelectedValue. Then you need to set a ComboBox.ValueMember

cmbPaymentType.DisplayMember = "PaymentTypeName"
cmbPaymentType.ValueMember = "PaymentTypeID"
cmbPaymentType.DataSource = _paymentTypes

cmbPaymentType.DataBindings.Add("SelectedValue", _data, "PaymentTypeID", False, DataSourceUpdateMode.OnPropertyChanged)
Fabio
  • 31,528
  • 4
  • 33
  • 72
  • Is there a combobox property that **does** raise databinding events? – Wibbler Jul 14 '15 at 07:44
  • Thank you, the first solution you proposed works perfectly. – Wibbler Jul 14 '15 at 08:09
  • 2
    I could be wrong, but according to this answer SelectedItem does raise databinding events just not until the control looses focus http://stackoverflow.com/questions/2883481/combobox-selecteditem-vs-selectedvalue – Charlie Jul 14 '15 at 12:51
-1

I'm a little confused, but it sounds like this is what you're asking:

  1. You have a Enumerable _data that contains several rows from the DB that you have bound to a DataGridView (DGV).

  2. You want to update a single row in the DGV using a control not in the DGV.

This is unusual. If your ComboBox was a cell in your DGV than all you have to do is handle the CellValueChanged event and everything should work fine.

That being said, you could have your ComboBox SelectedValue event update the cell value which will then fire the CellValueChanged.

Charlie
  • 2,004
  • 6
  • 20
  • 40
  • The UI design is unfortunately out of my control. Your proposed solution is a very roundabout way of doing things, I'd prefer to update the data object directly as the state of it used throughout the application. – Wibbler Jul 14 '15 at 07:49
  • I respectfully disagree. According the the link updating your UI instantly in this fashion is a valid approach for some applications. Evidently it wasn't for you, but that doesn't mean it's a wrong approach. http://stackoverflow.com/questions/2883481/combobox-selecteditem-vs-selectedvalue – Charlie Jul 14 '15 at 12:54