databinding a user control

databinding a user control

Old forum URL: forums.lhotka.net/forums/t/6283.aspx


dg78 posted on Thursday, January 29, 2009

Hello All,

 

Perharps a stupid question on databinding.

 

I use Csla 3.52 in WinForm VS 2008 vb.net.

 

I do databinding with drag and drop from data source windows.

Everything is OK with standard controls (textbox) and even derived controls.

Example of derived control :

  Partial Class dgTextBox

    Inherits System.Windows.Forms.TextBox

 

When I fetch data, these controls display the data and when I change the data in the textbox, the property changes. If I run Save, it is ok.

 

Now I use a user control, a composite control with a textbox (tbEssai) and a button :

 

Imports System.ComponentModel

 

<DefaultBindingProperty("Text")> _

Public Class ucEssai

 

  <System.ComponentModel.Bindable(True)> _

  Public Overrides Property Text() As String

    Get

      Return Me.tbEssai.Text

    End Get

    Set(ByVal value As String)

      Me.tbEssai.Text = value

    End Set

  End Property

 

End Class

 

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _

Partial Class ucEssai

    Inherits System.Windows.Forms.UserControl

 

The data binding is OK when I fetch data, the textbox tbEssai inside ucEssai displays the data.

But if I change the data with the keyboard, the property binded doesn't change.

 

I tried to add in ucEssai :

 

  Public Event ucEssaiChanged(ByVal sender As Object, ByVal e As System.EventArgs)

 

  Private Sub tbEssai_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) _

                                 Handles tbEssai.TextChanged

    RaiseEvent ucEssaiChanged(sender, e)

  End Sub

 

Or :

 

    Set(ByVal value As String)

      Me.tbEssai.Text = value

      RaiseEvent ucEssaiChanged(Me, New EventArgs)

    End Set

  End Property

 

It is the same : the binded property never changes.

 

Thanks for help.

 

Dominique

rsbaker0 replied on Thursday, January 29, 2009

Your control needs to properly implement the notification (INotifyPropertyChanged) that utimately informs the binding that the value has changed and needs to be written to the bindingsource. Unless you raise the event specific to the changed property (analagous to PropertyHasChanged() in CSLA BO's), no one ever knows your property value changed:

        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Text"))

dg78 replied on Thursday, January 29, 2009

Thanks for your answer.

 

So, I implement the INotifyPropertyChanged in the ucEssai and I put the RaiseEvent in the Set of the property.

 

The code is now :

 

Imports System.ComponentModel

 

<DefaultBindingProperty("Text")> _

Public Class ucEssai

 

  Implements INotifyPropertyChanged

 

  <System.ComponentModel.Bindable(True)> _

  Public Overrides Property Text() As String

    Get

      Return Me.tbEssai.Text

    End Get

    Set(ByVal value As String)

      Me.tbEssai.Text = value

      RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Text"))

    End Set

  End Property

 

  Public Event PropertyChanged(ByVal sender As Object, _

                      ByVal e As System.ComponentModel.PropertyChangedEventArgs) _

              Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

 

End Class

 

Is it the good place to put the RaiseEvent ?

 

My problem is that I don't go on the Set (and then on RaiseEvent) when I enter text in the textbox inside the user control or when I leave the user control.

I put a breakpoint and I never stop.

I go on the Set when it initialize the text property with the fetch but not when I enter characters in the user control. I don't understand why.

rsbaker0 replied on Thursday, January 29, 2009

Somehow you have to be monitoring the text changed event of your child control (tbEssai?) and pass it on via the PropertyChanged notification. I think you had some of this code in your original post.

Since you are essentially passing this property through from the exposed Text property on your user control, I'd just raise it when your tbEssai raises its notification internal to your control.

Also,in your setter you may need to check to see if the value is changed and skip the processing (depending on whether the tbEssai control raises the event even if you set it to the same value).

dg78 replied on Thursday, January 29, 2009

I use :

 

Private Sub tbEssai_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) _

                               Handles tbEssai.TextChanged

  RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Text"))

End Sub

 

When the text in tbEssai changed, I go on this RaiseEvent but I don't go on the setter of the BO property or on the setter of the Text property in ucEssai. The binding in this direction (control à BO) doesn't work.

I don't understand what's happen.

 

Have you (or others) (or do you know where I can find) a sample to use a user control (composite control) with binding in csla or only in winforms ? Thanks

rsbaker0 replied on Thursday, January 29, 2009

Have you actually tabbed off the control to see if the binding will write the value to the data source? Ordinarily, this happens during control validation versus the actual property change notification. I'm not an expert, but I've seen values in the control property that aren't written to the bound property until you tab off them. You can also change the binding itself in the designer (the "datasource update mode") and see if this makes a difference.

It's also possible to "bludgeon" the value into the bound property by interrogating the binding yourself and calling it's WriteValue method, but that's something I have done only as a last result.

dg78 replied on Friday, January 30, 2009

Yes I tabbed off the control but the binding don't write the value on the data source.

In the designer, in "datasource update mode", the default is OnValidation, I change it for On PropertyChanged, then I rebuild and it is the same.

I read there are some problems with OnValidation but I think there are also some problems with OnPropertyChanged.

 

There are no many samples about binding user controls. As often Microsoft do many samples for easy things but when it is more complicated, they don't.

rsbaker0 replied on Friday, January 30, 2009

Hmmmm. I started with this sample on CodeProject:

http://www.codeproject.com/KB/cs/BindBetterINotifyProperty.aspx

It's in C# though -- even so maybe you could compare what you are doing to the sample.

Copyright (c) Marimer LLC