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
Sanity Checks
Please refer to Library Versions to find out whether your platform specific PDFx version supports Sanity Checks.
In Debug mode, the PDFx performs certain resource expensive Sanity Checks that try to capture typical developer mistakes that are not caught at compile time.
Both the BindableExt’s Property and CachedValue methods ensure that the Property that is being pointed to in the first method parameter equals the Property from which either method is being called.
In the following example, the PDFx notices upon first access of the properties DependentPropertyMistake and CachedPropertyMistake that the way they use the PDFx is incorrect.
class WrongPDFXUsageDemonstration : BindableExt { private int _inputValue; public int InputValue { get { return _inputValue; } set { _inputValue = value; NotifyPropertyChanged(() => InputValue); } } public int DependentPropertyMistake { get { Property(() => InputValue) //Should point to DependentPropertyMistake .Depends(p => p.On(() => InputValue)); return InputValue*2; } } public int DependentPropertyProper { get { Property(() => DependentPropertyProper) .Depends(p => p.On(() => InputValue)); return InputValue * 2; } } public int CachedPropertyMistake { get { return CachedValue(() => InputValue, () => InputValue * 5); //Should point to CachedPropertyMistake } } public int CachedPropertyProper { get { return CachedValue(() => CachedPropertyProper, () => InputValue * 5); } } }