IsExpandable property of a folder like ER object.

IsExpandable property of a folder like ER object.

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


markell posted on Sunday, February 22, 2009

Dear sirs.
    My folder like object has an IsExpandable property, which is data bound in WPF, so that when the property is true an expansion icon is drawn immediately before the folder's name (much like in windows explorer).
    The folder's children are lazy loaded, the idea is that when the user expands the folder for the first time, its children are loaded, which may turn off the IsExpandable property, if there are no children at all.
    The property is implemented like this:
public bool IsExpandable
{
    get { return m_children == null || m_children.Count > 0; }
}
and the children are obtained through the Children property:
[NonSerialized]
private FolderStubList m_children;
public FolderStubList Children
{
    get
    {
        if (m_children == null)
        {
            m_children = FolderStubList.GetFolderStubList(this);
            // IsExpandable property might have changed - needs to check it.
        }
        return m_children;
    }
}

(where FolderStubList is ERLB)

My question is what is the best way to notify WPF that IsExpandable is changed? At first I thought to call PropertyHasChanged("IsExpandable") from within the Children property getter. But that marks the folder as dirty, which is wrong.
I can, of course, copy the contents of the PropertyHasChanged method omitting the call to MarkDirty, but I am wondering if there is a better way.

Thanks.

markell replied on Sunday, February 22, 2009

The way I solved it in my code is by changing the PropertyHasChanged method like this:

if (!IsCalculatedProperty(propertyName))
{
  MarkDirty(true);
}

where IsCalculatedProperty is a new protected virtual method, returning false by default. My folder object overrides it and returns true for the IsExpandable property.

Any feedback?

RockfordLhotka replied on Sunday, February 22, 2009

If all you want to do is raise the PropertyChanged event, then use OnPropertyChanged(), not PropertyHasChanged().

markell replied on Sunday, March 01, 2009

Thanks, Rocky, for the reply.

At first, that is exactly what I did, but then I had to copy almost all of the PropertyHasChanged method, because all it really does is mark the BO as dirty and then trigger the PropertyChanged event (taking WPF/WinForms into account).
I cannot be 100% percent sure that any UI written on top of my BO will be WPF. It might be WinForms as well, so I have to copy all that logic from the PropertyHasChanged method.
Is that what you would have done in my place?

RockfordLhotka replied on Sunday, March 01, 2009

The complexity in raising PropertyChanged for Windows Forms only comes into play because multiple properties might be indirectly affected by CheckRules(). If all you are doing is changing a single property and not invoking business rules that may affect other properties, then you should feel comfortable just raising PropertyChanged.

 

Yes, it might be slightly less efficient in a WinForms setting, but not enough to complicate your code so much.

 

Think about it this way. If you use LINQ to SQL, or the Entity Framework, or just about any other code-gen model out there, every property that changes will raise a PropertyChanged event. And each time that happens, WinForms will refresh all bindings. And people build software with that stuff all the time, regardless of the fact that it is inefficient.

 

Most of your CSLA code will be more efficient, because of my optimizations. But if you have one property here or there that acts “normally” that really isn’t going to harm you.

 

Rocky

markell replied on Sunday, March 01, 2009

Thanks, Rocky.
I guess you are right. I will undo my changes and just trigger the PropertyChanged event. I guess this is not going to be the 20% of the code that takes up 80% of the time.

Copyright (c) Marimer LLC