Rockford Lhotka

 Wednesday, September 28, 2005
« Nice little VB 2005 enhancement | Main | Windows Forms binding issue: A component... »

This is the conclusion (for now) of the issue with Windows Forms data binding that I discussed in an earlier entry.


To recap, the issue occurs in detail forms built using data binding. The current control’s value isn’t refreshed when the user tabs off the control. If the data source (business object or smart DataTable with a partial class) changed the value due to business logic that change is not reflected in the UI, even though the changed value is in the data source.


In talking to the data team at Microsoft, it turns out that this is a bug and will likely be fixed in some future service pack. At this late stage of the game however, it won’t be fixed for release of VS 2005.


Fortunately they were able to come up with a decent workaround in the meantime. The workaround is done in the UI and involves hooking an event from each Binding object, then in the event handler forcing the current value to be refreshed from the data source.


To set this up, add the following code to your form:


  Private Sub HookBindings()


    For Each ctl As Control In Me.Controls

      For Each b As Binding In ctl.DataBindings

        AddHandler b.BindingComplete, AddressOf ReadBinding




  End Sub


  Private Sub ReadBinding(ByVal sender As Object, _

    ByVal e As BindingCompleteEventArgs)




  End Sub


Then just make sure to call HookBindings in your form’s Load event or constructor. Ideally this is the kind of thing you’d do in a base form class, then make all your normal forms just inherit from that base so there’s no extra code in each actual form.


The HookBindings method loops through all controls on the form, and all Binding objects for each control. Every Binding object’s BindingComplete event is hooked to the ReadBinding method – making it the event handler for all Binding objects.


The ReadBinding method handles all BindingComplete events for the form. Any time that event is raised this method merely forces data binding to read the current value from the data source and refresh the control.


Since BindingComplete is raised after the user has tabbed off a control and the binding is “complete”, this refresh of the display value ensures that the current control does actually contain the value from the data source even if the data source changed the value.