Another Binding Question... Even Simpler...

Z

ZorpiedoMan

Why Doesn't THIS work:
-----------------------------------------------------------
A Windows Form has three controls:
TextBox1
BindButton
ShowTextButton
ChangeTextButton

Code:

Public Class SimpleClass

Private myText as String

Public Sub New(NewText as String)
myText = NewText
End Sub

Public Property Text() As String
Get
Return myText
End Get
Set(Value as String)
myText = Value
End Set
End Property

End Class

Private mySimpleClass as new SimpleClass("Hello")

Private Sub BindButtonClick(...)...
TextBox1.DataBindings.Add("Text", mySimpleClass, "Text")
End Sub

Private Sub ShowTextButtonClick(...)...
MsgBox(mySimpleClass.Text)
End Sub

Private Sub changeTextButtonClick(...)...
mySimpleClass.Textx = "Goodbye"
End Sub
-----------------------------------------------------------

Ok... Here's what happens...

1. Run the program. No problem
2. Click The ShowText Button. "Hello" is shown. Fine.
3. Click the BindButton. TextBox1 shows "Hello". Still Fine.
4. Type "World" into TextBox1.
5. Click the ShowText Button. "World" is shown. So Far So Good...
6. Click the ChangeText Button. PROBLEM: TextBox1 still shows
"World". NOT Good.
7. Click the ShowText Button. "GoodBye" is shown. As Expected.

Why this one-way behavior? How do I get my SimpleClass to notify the
Textbox it needs to change?


--Zorpy

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!
 
O

One Handed Man \( OHM - Terry Burns \)

It doesent work because you need to inform the binding manager on the form
that something has changed.

Declare a public Event TextChanged As Event Handler

In your Set Property, Raise the event if the text is different from before
by calling a sub which raises this event TextChanged.

Then it will work.



--

OHM ( Terry Burns )
. . . One-Handed-Man . . .

Time flies when you don't know what you're doing
 
O

One Handed Man \( OHM - Terry Burns \)

Full Example using check boxes

Here we have an Class Person. Within it we declare a public event called
CheckedChanged, this is made up of the property which the binding manager
listens for an event for once binding has been set. When the Property
changes from checked to unchecked we call a helper function which raises
this event and the binding manager syncs the control ( rad1 ) to this
property.

Button1.click changes the property of the aPerson object to checked, this is
then reflected through the bindings in the rad1 state.

On_Load is where we set the bindings

HTH

Private WithEvents aPerson As New Person

Public Class Person

Public Event CheckedChanged As EventHandler

Private m_checked As Boolean

Public Sub New()
m_checked = False
End Sub

Public Property Checked() As Boolean
Get
Return m_checked
End Get
Set(ByVal value As Boolean)
m_checked = value
PropertyChanged(EventArgs.Empty)
End Set
End Property

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
rad1.DataBindings.Add("Checked", aPerson, "Checked")
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
aPerson.checked = True
End Sub
 
C

Cor Ligthert

Hi Zorpy,

I cannot answer your question, however when you do this it works.

mySimpleClass.Text = "Goodbye"
Me.BindingContext(mySimpleClass).ResumeBinding()

I hope it helps anyhow?

Cor
 
Z

ZorpiedoMan

PropertyChanged is supposed to be part of IpropertyChange which is
supposed to be in system.ComponentModel, yet I don't seem to have it???

Where the heck is it... even documentation is coming up blank on
"PropertyChanged" ...



--Zorpy

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!
 
Z

ZorpiedoMan

I can't get this to work either...

Did I follow your suggestion correctly:

Public Class SimpleClass


Private myText As String
Public Event TextChanged As EventHandler

Public Sub New(ByVal NewText As String)
myText = NewText
End Sub

Public Property Text() As String
Get
Return myText
End Get
Set(ByVal Value As String)
If myText <> Value Then
Tellme()
End If
myText = Value
End Set
End Property

Private Sub Tellme()
RaiseEvent TextChanged(Me, New EventArgs)
End Sub

End Class

--Zorpy

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!
 
C

Cor Ligthert

I can't get this to work either...Did you try what I sand more than an half hour ago?

Cor
 
J

Jay B. Harlow [MVP - Outlook]

Zorpy,
In addition to the other comments, You need to define an Event as
EventHandler that has the same name as the Property with Changed on the end.
For example your Text property would need a TextChanged event, a Count
Property would need a CountChanged event.

This is explained in the following article

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnadvnet/html/vbnet02252003.asp

Here is an example binding to multiple properties, with notifications:

Public Class Person

Public Event Text1Changed As EventHandler
Public Event Text2Changed As EventHandler

Private m_text1 As String
Private m_text2 As String

Public Sub New()
m_text1 = String.Empty
m_text2 = String.Empty
End Sub

Public Property Text1() As String
Get
Return m_text1
End Get
Set(ByVal value As String)
m_text1 = value
OnText1Changed(EventArgs.Empty)
End Set
End Property

Public Property Text2() As String
Get
Return m_text2
End Get
Set(ByVal value As String)
m_text2 = value
OnText2Changed(EventArgs.Empty)
End Set
End Property

Protected Overridable Sub OnText1Changed(ByVal e As EventArgs)
RaiseEvent Text1Changed(Me, e)
End Sub

Protected Overridable Sub OnText2Changed(ByVal e As EventArgs)
RaiseEvent Text2Changed(Me, e)
End Sub

End Class


Public Class PersonForm
Inherits System.Windows.Forms.Form

' ... designer generated code

Private aPerson As New Person

Private Sub Person_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.TextBox1.DataBindings.Add("Text", aPerson, "Text1")
Me.TextBox2.DataBindings.Add("Text", aPerson, "Text2")
End Sub

End Class


Hope this helps
Jay
 
Z

ZorpiedoMan

Cor -

No I didn't, because I don't think it really applies. The sample I'm
giving is just that - a stripped down version to demonstrate the
problem. The property of the Class will be getting changed
programitacally, not from the form, so Me.BindingContext is not exposed
to the class. Pretend for a moment that the Text property of my class
keeps changing every second to show the current time. The change is
taking place in the class, and the form needs to be notified of the
change to update the textbox. The class has no idea if it is on a form
or not.

I think the PropertyChanged suggestion is probably the right one, I just
can't find it anywhere.

--Zorpy

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!
 
O

One Handed Man \( OHM - Terry Burns \)

CheckedChanged is the event which is listned for. The word Changed is
appended to the property of the class for which you raise the event.



--

OHM ( Terry Burns )
. . . One-Handed-Man . . .

Time flies when you don't know what you're doing
 
O

One Handed Man \( OHM - Terry Burns \)

Sorry some was missed, here u go

Public WithEvents aPerson As New Person

Public Class Person

Public Event CheckedChanged As EventHandler

Private m_checked As Boolean

Public Sub New()

m_checked = False

End Sub

Public Property Checked() As Boolean

Get

Return m_checked

End Get

Set(ByVal value As Boolean)

m_checked = value

PropertyChanged(EventArgs.Empty)

End Set

End Property

Protected Overridable Sub PropertyChanged(ByVal e As EventArgs)

RaiseEvent CheckedChanged(Me, e)

End Sub

End Class




--

OHM ( Terry Burns )
. . . One-Handed-Man . . .

Time flies when you don't know what you're doing
 
Z

ZorpiedoMan

No luck here either. Here is the latest code as you suggested:

Public Class SimpleClass

Private myText As String
Public Event TextChanged As EventHandler

Public Sub New(ByVal NewText As String)
myText = NewText
End Sub

Public Property Text() As String
Get
Return myText
End Get
Set(ByVal Value As String)
If myText <> Value Then
OnTextChanged(EventArgs.Empty)
End If
myText = Value
End Set
End Property

Protected Overridable Sub OnTextChanged(ByVal e As EventArgs)
RaiseEvent TextChanged(Me, e)
End Sub

End Class

--Zorpy

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!
 
C

Cor Ligthert

I tested it and it works and it is very simple to use, however writing one
row in your program is to much of course to try.

Cor
 
C

Cor Ligthert

Jay,

That what I showed worked perfectly, it reset the binding, however in my
opinion that should go automaticly when the form is refresed.

Cor
 
J

Jay B. Harlow [MVP - Outlook]

Zorpy,
The code I gave works.

Look closely at my & Terry's code compared to yours.
If myText <> Value Then
OnTextChanged(EventArgs.Empty)
End If
myText = Value

You raise the event telling the binding that the value changed, it goes OK,
let me get the old value, then you set the new value.

The Changed event needs to occur AFTER the value changed...
If myText <> Value Then
myText = Value
OnTextChanged(EventArgs.Empty)
End If

Hope this helps
Jay
 
J

Jay B. Harlow [MVP - Outlook]

Zorpy
I should add, if you want pre-notification the .NET convention is to use a
propertyChanging event.

I normally make my Changing events cancelable.

Something like:

Public Class SimpleClass

Public Event TextChanging As
System.ComponentModel.CancelEventHandler
Public Event TextChanged As EventHandler

Private myText As String

Public Sub New(ByVal NewText As String)
myText = NewText
End Sub

Public Property Text() As String
Get
Return myText
End Get
Set(ByVal Value As String)
If myText <> Value Then
Dim e As New System.ComponentModel.CancelEventArgs
OnTextChanging(e)
If e.Cancel Then Exit Property
myText = Value
OnTextChanged(EventArgs.Empty)
End If
End Set
End Property

Protected Overridable Sub OnTextChanging(ByVal e As
System.ComponentModel.CancelEventArgs)
RaiseEvent TextChanging(Me, e)
End Sub

Protected Overridable Sub OnTextChanged(ByVal e As EventArgs)
RaiseEvent TextChanged(Me, e)
End Sub

End Class

If you wanted to include old & new values on the Changing event, you can
derive a class from CancelEventHandler and add the values as properties... I
normally include the old & new values on my Changing events...

Hope this helps
Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top