views:

227

answers:

1

I have a UserControl, with a TextBox and a databound property - Value. Value can be any object such as a Color, Array, Font etc. Any time the text changes, the property Value is changed as long as it is valid.

Looking at the msdn article: How to: Apply the PropertyNameChanged Pattern , it says I should use the PropertyNameChanged Event pattern from the control side.

Now, If I have DataSourceUpdateMode = OnValidate, then I don't even need to apply this pattern. If, say. my Value property is bound to a colour field in a business object, then after I type red, in the textbox and tab to another field, then any other fields on the form, that bind to the same colour field, are updated immediately.

If, however, my DataSourceUpdateMode = OnPropertyChange, I would expect all other fields, on the form, to update as soon as I press 'd' (as in re'd').

This doesn't happen. So, I apply the aforementioned PropertyNameChanged Pattern and it still doesn't happen.

However, If I remove the PropertyNameChanged event and, instead, use INotifyPropertyChanged, it works perfectly.

My problem is, that according to the article, INotifyPropertyChanged is supposed to be used by your business objects and not the user control.

It works, but I don't want to run into any future problems.

Anyone have any idea what's going on?

ETA:

Assuming it is ok to use INotifyPropertyChanged, I now have a further problem. I don't want users to have to subscribe to the 'PropertyChanged' event, and then examine the arguments to see if the property 'Value' sent it. So, I add:

Public Event ValueChanged As EventHandler(Of EventArgs)

This breaks the binding. The source is not even updated on validation, let alone on property change.

I presume I have to rename the ValueChanged event to FeckingValueChanged or something.

I wouldn't mind so much if the framework actually did something with the raised ValueChange event in the first place!

A: 

Ok, I've found that the code supplied at MSDN is incorrect. Below, I've highlighted the incorrect parts and show the corrections:

Incorrect

Public DataSourceChanged As EventHandler

Private Sub OnDataSourceChanged() 
    If (DataSourceChanged IsNot Nothing) Then
        DataSourceChanged(Me, New EventArgs())
    End If
End Sub

Correct

Public **Event** DataSourceChanged As EventHandler

Private Sub OnDataSourceChanged() 
    If (DataSourceChangedEvent IsNot Nothing) Then
        **RaiseEvent** DataSourceChanged(Me, New EventArgs())
    End If
End Sub

I've found you have to declare this event in this precise way, otherwise databinding, OnPropertyChanged, will not work.

For instance, the following will not work, for some reason:

Public Event DataSourceChanged As EventHandler(Of EventArgs)

Using INotifyPropertyChanged also works, but you can't also have the expected PropertyNameChanged event, to which users would expect to be able to subscribe to.

Jules