PDFx – Property Dependency Framework – Part VII, Dynamic External Property Dependencies

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:

Dynamic External Property Dependencies

Declarative Usage

As shown in External Property Dependencies, the declarative PDFx API allows you to register a dependency on a property that resides in any INotifyPropertyChanged-instance different from the owner of the dependent Property.

If the owner of the source property can be swapped out at runtime (or start off as null), you can instruct PDFx to listen for changes of the owner object:

class SourceClass : INotifyPropertyChanged
{
	private AnyType _sourceProperty;
	public AnyType SourceProperty
	{
		get { return _sourceProperty; }
		set
		{
			_sourceProperty = value;
			OnPropertyChanged("SourceProperty");
		}
	}
}

class DestinationClass : BindableExt
{
	private SourceClass _dynamicSource;
	private SourceClass DynSource
	{
		get { return _dynamicSource; }
		set
		{
			_dynamicSource = value;
			NotifyPropertyChanged(() => DynSource);
		}
	}

	public AnyOtherType TargetProperty
	{
		get
		{
			Property(() => TargetProperty)
		            .Depends(p => p.On(() => DynSource, k => k.SourceProperty)); 
                        //Note that the first parameter of the On method is a delegate

			//SourceProperty has changed. Do Something with it and return.
		}
	}

	public void ChangeSource()
	{
		DynSource = new SourceClass();
	}
}

Overloads of the methods On and AndOn both allow you to pass in an INotifyPropertyChanged instance as the first parameter and point to any property of that instance in the Lambda Expression you pass in as the second parameter.
To support hot swapping of the INotifyPropertyChanged instance, you pass in a delegate to the On and AndOn overloads, which points to the Property that contains the Source Property owner.

Example

The source code of this example can be found in ViewModel DynamicExternalDependencyVM which is part of the WPFSample’s source code.

Let’s assume we are required to implement the following graph:

DynamicExternalPropertyDependenciesI.png

By clicking the “Use External Source”-buttons, the user can change the source “External Source” that ultimately feeds into the Destination object:

DynamicExternalPropertyDependenciesII.png

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 represent the depicted graph in C#:

public class DynamicExternalDependencyVM : BindableExt
{
	public DynamicExternalDependencyVM()
	{
		ExternalSource1 = new ExternalSource();
		ExternalSource2 = new ExternalSource();
		Destination = new DestinationVM() { ExternalSource = ExternalSource1 };
	}

	public DestinationVM Destination { get; set; }
	public ExternalSource ExternalSource1 { get; set; }
	public ExternalSource ExternalSource2 { get; set; }

	private DelegateCommand _useExternalSource1Command;
	public DelegateCommand UseExternalSource1Command
	{
		get
		{
			return _useExternalSource1Command = _useExternalSource1Command ?? new DelegateCommand(() => Destination.ExternalSource = ExternalSource1);
			//Hotswap ExternalSource
		}
	}

	private DelegateCommand _useExternalSource2Command;
	public DelegateCommand UseExternalSource2Command
	{
		get
		{
			return _useExternalSource2Command = _useExternalSource2Command ?? new DelegateCommand(() => Destination.ExternalSource = ExternalSource2);
			//Hotswap ExternalSource
		}
	}

	public class DestinationVM : BindableExt
	{
		public int A1
		{
			get
			{
				Property(() => A1)
					.Depends(p => p.On(() => B1)
						        .AndOn(() => ExternalSource, k => k.A1));
				//Tell the PDFx that ExternalSource might get hotswapped

				return B1 + ExternalSource.A1;
			}
		}

		private ExternalSource _externalSource;
		public ExternalSource ExternalSource
		{
			get { return _externalSource; }
			set
			{
				_externalSource = value;
				NotifyPropertyChanged(() => ExternalSource);
			}
		}

		private int _b1;
		public int B1
		{
			get { return _b1; }
			set
			{
				_b1 = value;
				NotifyPropertyChanged(() => B1);
			}
		}
	}

	public class ExternalSource : BindableExt
	{
		public int A1
		{
			get
			{
				Property(() => A1)
					.Depends(p => p.On(() => B1));

				return 3 * B1;
			}
		}

		private int _b1;
		public int B1
		{
			get { return _b1; }
			set
			{
				_b1 = value;
				NotifyPropertyChanged(() => B1);
			}
		}
	}
}

4 thoughts on “PDFx – Property Dependency Framework – Part VII, Dynamic External Property Dependencies

  1. Pingback: PDFx – Property Dependency Framework – Part I, Introduction | //InterKnowlogy/ Blogs

  2. Pingback: PDFx – Property Dependency Framework – Part II, Library Versions | //InterKnowlogy/ Blogs

  3. Pingback: PDFx – Property Dependency Framework – Part III, Getting started | //InterKnowlogy/ Blogs

  4. Pingback: PDFx – Property Dependency Framework – Part VIII, Collection Dependencies | //InterKnowlogy/ Blogs

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>