BindableBase errata?

BindableBase errata?

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


Brian Criswell posted on Friday, August 11, 2006

Debugging a change in code upgraded from CSLA 1.52 to 2.0.3 caused me to stumble upon a changed to BindableBase that was different from the book but did not seem to be listed in any errata.

protected virtual void OnPropertyChanged(string propertyName)
{
      PropertyChangedEventHandler nonSerializableHandlers =
        _nonSerializableHandlers;

      if (nonSerializableHandlers != null)
        nonSerializableHandlers.Invoke(this,
          new PropertyChangedEventArgs(propertyName));
      PropertyChangedEventHandler serializableHandlers =
        _serializableHandlers;

      if (serializableHandlers != null)
        serializableHandlers.Invoke(this,
          new PropertyChangedEventArgs(propertyName));
}

The green lines are not in the book's code, and I could not find an errata article regarding it.  Instead, in the book, the instances of the event handlers are invoked directly.  The reason I bring this up is that the act of assigning another reference to the event handlers seems to cause spurious calls to the add and remove blocks of the event.

RockfordLhotka replied on Friday, August 11, 2006

Ahh, excellent! I think you've just helped me solve a problem that's been nagging me for some time now...

That change came late in the game, as a result of some discussions around thread safety. But I think what you are seeing is causing a duplicate eventing issue I've been chasing off and on - I'll test and see.

PeterRow replied on Monday, August 14, 2006

Hi,

In a (related?) query/problem, I have updated the code in Brian's code to directly use the member variables that store the references.

I have a collection of editable child objects (Entries) exposed as a property of a dictionary BO within my app that the user can edit. When the [Save] button is bound to the IsSavable property then it all works fine and dandy the first time, i.e. I edit one of the entries in the collection (in a databound listview) via a pop-up dialog, the Save button becomes enabled when changes are made to the entry, click [OK] and then [Save]. The change to the entry is saved fine and the save button becomes disabled again.

However, if I then change another entry (or even the same one) then the save button does not become become enabled. The event handler added to the Entries collection property of my Dictionary BO does not appear to be fired (and hence attached).

If I then edit another entry, change the same 2 fields as before (simple textboxes) then when I tab off the 2nd one I get a NullReferenceException on the:  if (_serializableHandlers != null) line in the OnPropertyChanged eventhandler in BindableBase. The _serializableHandlers member is null, but why it should cause a NullReferenceException is strange, can't a null be compared to a null?

I guess the real problem is why is it null in the first place. Any ideas on what to look into would be much appreciated. I've probably left out some saliant piece of info' so please ask if your looking to help and need extra details.

Regards,

Peter

PeterRow replied on Tuesday, August 15, 2006

As a side note, if I drop on a BindingSource and set the DataSource to my object and then add bindings with code such as:

fromQuarterComboBox.DataBindings.Add(New Binding("SelectedValue", entryBindingSource, "FromQuarterId", True))

... which replaced original bind code which called this custom method:

public static void BindField(
Control control, string propertyName, object dataSource, string dataMember, ConvertEventHandler formatHandler, ConvertEventHandler parseHandler)
{
    Binding binding = control.DataBindings[propertyName];
    if(binding != null)
        control.DataBindings.Remove(binding);
    binding = new Binding(propertyName, dataSource, dataMember);
    if(formatHandler != null)
        binding.Format += new ConvertEventHandler(formatHandler);
    if(parseHandler != null)
        binding.Parse += new ConvertEventHandler(parseHandler);
    control.DataBindings.Add(binding);
}

.. excuse the formatting, then I don't get the error. The binding source must obviously be doing something differently but what is the key to this I guess.

Copyright (c) Marimer LLC