The PDFx is a lightweight open source .NET library that allows developers to describe dependencies between Properties in declarative C# code. Once relationships are registered, the framework monitors property changes and ensures that the INotifyPropertyChanged.PropertyChanged event is fired for all directly and indirectly dependent properties in a very efficient way. The library is available for WPF, Silverlight, WinRT (Windows Store) and Windows Phone.
I’ve developed the PDFx as an InterKnowlogy RECESS project and published the source code and examples on codeplex.
In a series of blog posts I am going to cover the library’s most important features:
- Part I: Introduction
- Part II: Library Versions
- Part III: Getting Started
- Part IV: Using PDFx with an existing 3rd party framework
- Part V: Simple Property Dependencies
- Part VI: External Property Dependencies
- Part VII: Dynamic External Property Dependencies
- Part VIII: Collection Dependencies
- Part IX: Dynamic Collection Dependencies
- Part X: Caching
- Part XI: Smart Property Changed Notification
- Part XII: Callbacks
- Part XIII: Sanity Checks
- Part XIV: Data Delegation
- Part XV: Two Way Converters
- Part XVI: One Way Converters
Collection Dependencies
Declarative Usage
The PDFx allows you to register dependencies not only on single objects’s properties, but also on ObservableCollections’ children’s properties, given that they support the INotifyPropertyChanged interface:
class Demonstration : BindableExt { DependencyFrameworkObservableCollection<ChildClass> _children = new DependencyFrameworkObservableCollection<ChildClass>(); public AnyType CombinationOfAllChildren { get { Property(() => CombinationOfAllChildren) .Depends(p => p.OnCollectionChildProperty(_children, k => k.ChildProperty)); //Do something with all children and return } } class ChildClass : INotifyPropertyChanged { private AnyType _childProperty; public AnyType ChildProperty { get { return _childProperty; } set { _childProperty = value; OnPropertyChanged("ChildProperty"); } } } }
Overloads of the methods OnCollectionChildProperty and AndOnCollectionChildProperty both allow you to pass in a DependencyFrameworkObservableCollection instance as the first parameter and point to any property of that collection’s children in the Lambda Expression you pass in as the second parameter.
DependencyFrameworkObservableCollection vs. ObservableCollection / INotifyCollectionChanged
It is recommended to use the PDFx’s API with DependencyFrameworkObservableCollections when dependencies on collection’s children are to be registered, since the DependencyFrameworkObservableCollection offers significant property dependency performance advantages over the ObservableCollection or any other collection that implements INotifyCollectionChanged. It is, however, not required. ObservableCollections and other collections that implement INotifyCollectionChanged satisfy the API as well.
Example
The source code of this example can be found in ViewModel SimpleCollectionDependencyDemonstrationVM which is part of the WPFSample’s source code.
Let’s assume we are required to implement the following system:
Green circles stand for Input Properties while purple circles indicate calculated properties. The arrows show the underlying math operations as well as the property dependencies.
Using the PDFx, we can easily implement the depicted system:
class DestinationVM : BindableExt { public DestinationVM() { Children.Add(new ChildVM(_children)); Children.Add(new ChildVM(_children)); Children.Add(new ChildVM(_children)); } private DependencyFrameworkObservableCollection<ChildVM> _children = new DependencyFrameworkObservableCollection<ChildVM>(); public DependencyFrameworkObservableCollection<ChildVM> Children { get { return _children; } } public DelegateCommand AddCommand { get { return new DelegateCommand(() => Children.Add(new ChildVM(Children))); } } public int A1 { get { Property(() => A1) .Depends(p => p.On(() => B1).AndOn(() => B2)); return B1 + B2; } } public int B1 { get { Property(() => B1) .Depends(p => p.OnCollectionChildProperty(Children, k => k.A1)); //Note the usage of the OnCollectionChildProperty method if (Children.Count == 0) return 0; return Children.Select(k => k.A1).Sum(); } } private int _b2 = 0; public int B2 { get { return _b2; } set { _b2 = value; NotifyPropertyChanged(() => B2); } } class ChildVM : BindableExt { private DependencyFrameworkObservableCollection<ChildVM> _children; public ChildVM(DependencyFrameworkObservableCollection<ChildVM> children) { _children = children; } private int _b1 = 1; public int B1 { get { return _b1; } set { _b1 = value; NotifyPropertyChanged(() => B1); } } public int A1 { get { Property(() => A1) .Depends(p => p.On(() => B1)); return B1 * 3; } } public DelegateCommand RemoveCommand { get { return new DelegateCommand(() => _children.Remove(this)); } } } }
Pingback: PDFx – Property Dependency Framework – Part I, Introduction | //InterKnowlogy/ Blogs
Pingback: PDFx – Property Dependency Framework – Part II, Library Versions | //InterKnowlogy/ Blogs
Pingback: PDFx – Property Dependency Framework – Part IV, Using PDFx with an existing 3rd party framework | //InterKnowlogy/ Blogs
Pingback: PDFx – Property Dependency Framework – Part VII, Dynamic External Property Dependencies | //InterKnowlogy/ Blogs
Pingback: PDFx – Property Dependency Framework – Part IX, Dynamic Collection Dependencies | //InterKnowlogy/ Blogs
Pingback: PDFx – Property Dependency Framework – Part X, Caching | //InterKnowlogy/ Blogs
Pingback: PDFx – Property Dependency Framework – Part XI, Smart Property Changed Notification | //InterKnowlogy/ Blogs
Pingback: PDFx – Property Dependency Framework – Part XII, Callbacks | //InterKnowlogy/ Blogs
Pingback: PDFx – Property Dependency Framework – Part XIII, Sanity Checks | //InterKnowlogy/ Blogs
Pingback: PDFx – Property Dependency Framework – Part XIV, Data Delegation | //InterKnowlogy/ Blogs
Pingback: PDFx – Property Dependency Framework – Part XV, Two Way Converters | //InterKnowlogy/ Blogs
Pingback: PDFx – Property Dependency Framework – Part XVI, One Way Converters | //InterKnowlogy/ Blogs
Pingback: PDFX: First Thoughts | //InterKnowlogy/ Blogs