BindingSource calls Child List Property way too many times

BindingSource calls Child List Property way too many times

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


lukky posted on Thursday, February 26, 2009

Hi,

This is a Windows Forms issue.

I have an EditableRoot BO that has an EditableChildList managed property.

The Child property on the root BO is declared and defined as follows:

private static PropertyInfo<LabelList> LabelsProperty = RegisterProperty(new PropertyInfo<LabelList>("Labels", "Labels"));

public LabelList Labels
        {
            get
            {
                if (!FieldManager.FieldExists(LabelsProperty))
                    LoadProperty(LabelsProperty, LabelList.NewLabelList());
                return GetProperty(LabelsProperty);
            }
        }

On the form, I have 2 BindingSources, one for the Parent BO, and one for the Child property.

The Child BindingSource's DataSource points to the Parent BindingSource, and its DataMember points to the Labels property on the Parent BindingSource. All this is done through VS.NET designer.

The issue is that when I set the ParentBindingSource.DataSource in code, the Labels property gets called around 10 times for no apparent reason. There is not even one control bound to the Child BindingSource yet !!!

Does anyone have an idea what could cause the Labels property getter to be called so many times ?

Thank you.

ajj3085 replied on Thursday, February 26, 2009

You could set a breakpoint in the getter and look at the call stack to see.

tetranz replied on Thursday, February 26, 2009

I sometimes notice the same thing. WinForms databinding does seem to generate a scary number of events.

Are you setting parent properties and causing property changed events? ie, doing this.MyProperty = newValue or something coming in from the UI.

This may not answer your question directly but in WinForms databinding, any property change event causes ALL bound properties to refresh. I don't know if MS have ever called this as a bug or a feature but apparently it's changed in WPF where the more sensible thing happens, ie, only the property that changed is refreshed. "All properties" includes child collections so any change in a property on your parent will cause the child binding source to reread the collection and fire a ListChanged reset event.

The refreshes obviously happen quite efficiently because it's never really been a problem to me but I often keep it in mind when I'm updating several properties within a BO and I need the UI to follow, I might use LoadProperty for all but the last and then set this.MyProperty on the last. That way I only send one PropertyChanged event so reducing unnecessary UI refreshes but ... that's clearly somewhat dangerous and klugy and means that my BOs are not compatible between WinForms and WPF.

Some of these issues are probably more in my mind than real problems but it just kind of irks me to think of my child grid refreshing it's rows just because I changed an unrelated checkbox on the parent. In your example, obviously the FieldManager.FieldExists test means that it doesn't do much so it's probably not a big deal.

Setting RaiseListChangedEvents on your parent binding source to false while you set it's DataSource might help although that may cause other effects.

Ross

lukky replied on Thursday, February 26, 2009

@ajj:

I have looked at the stack trace, but it's a jungle of data binding related calls, so I don't really understand the intricacies of it all. Sad [:(]

@Ross:

The only code I call that generates a cascade of calls to the getter is simply setting the parent BindingSource.DataSource.

What caused me to check into this was that on top of my "Labels" property, I have another property called "BoxLabels" which basically returns a filtered list of labels, and it uses a Linq to CSLA query. I first noticed the multiple calls in THAT property getter, but I've isolated it back to the "real" managed property to make sure it wasn't the Linq query that was somehow causing the list to be refreshed.

Though I haven't noticed any slow down in performance due to the multiple calls, I feel it's not very efficient to have the DataBinding query my filtered property multiple times.

I'll try the RaiseListChangedEvent property. Thanks.

@All:

Anyone has other ideas on how to nail this down ?

Thank you

lukky replied on Friday, April 24, 2009

As a follow-up on this subject, I have posted the following thread on MSDN forums:

http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/fb6b763c-5f0a-4594-94c0-19b6b7eb8c61

In this post, I explain that even on a bare bone .NET object (non CSLA), the first time that you set an object as a BindingSource's DataSource, the get accessors are called three times on all properties bound to a Windows Forms Control. If on the other hand you bind the Control directly to the object without using a BindingSource in between, then this behavior is not seen.

This is obviously a Windows Forms issue, but there is one more reason I've seen why my getters are called so many times on my CSLA BOs, and it's because of validation rules. This part I could handle within my BO logic, but I'd really like to hear from someone with knowledge about the BindingSource issue.

Thank you.


Copyright (c) Marimer LLC