PDFx – Property Dependency Framework – Part IX, Dynamic Collection 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 Collection Dependencies

Declarative Usage

As described in Collection Dependencies, the PDFx allows you to register dependencies not only on single objects’s properties, but also on ObservableCollections’ children’s properties.

If the Collection is hotswappable, you can instruct the PDFx to listen for replacements of the entire collection instance:

class Demonstration : BindableExt
{
	DependencyFrameworkObservableCollection<ChildClass> _children = new DependencyFrameworkObservableCollection<ChildClass>();
	public DependencyFrameworkObservableCollection<ChildClass> Children
	{
		get { return _children; }
		set
		{
			_children = value;
			NotifyPropertyChanged(() => Children);
		}
	}

	public AnyType CombinationOfAllChildren
	{
		get
		{
		       Property(() => CombinationOfAllChildren)
	                  .Depends(p => p.OnCollectionChildProperty(() => Children, k => k.ChildProperty));
		//Note how a delegate points to the Collections' property, 
                //thereby allowing the collection to be swapped out.

		//Do something with all children and return
		}
	}

	public void ReplaceChildren()
	{
		Children = new DependencyFrameworkObservableCollection<ChildClass>();
	}

	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.
To support hot swapping of the Collection’s instance, you pass a delegate to the OnCollectionChildProperty and AndOnCollectionChildProperty overloads, which points to the Property that contains the Collection.

Example

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

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

DynamicCollectionDependencyI.png

By clicking the “Click here to use Children”-buttons, the user can change the source collection that ultimately feeds into the Destination object:

DynamicCollectionDependencyII.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 implement the depicted system:

class DestinationVM : BindableExt
{
	public DestinationVM()
	{
		Children1 = new DependencyFrameworkObservableCollection<ChildVM>();
		Children2 = new DependencyFrameworkObservableCollection<ChildVM>();
		Children = Children1;

		Children1.Add(new ChildVM(Children1));
		Children1.Add(new ChildVM(Children1));
		Children1.Add(new ChildVM(Children1));

		Children2.Add(new ChildVM(Children2) { B1 = 2 });
		Children2.Add(new ChildVM(Children2) { B1 = 2 });
		Children2.Add(new ChildVM(Children2) { B1 = 2 });
	}

	private DependencyFrameworkObservableCollection<ChildVM> _children = new DependencyFrameworkObservableCollection<ChildVM>();
	public DependencyFrameworkObservableCollection<ChildVM> Children
	{
		get { return _children; }
		set
		{
			_children = value;
			NotifyPropertyChanged(() => Children);
		}
	}
	
	public DependencyFrameworkObservableCollection<ChildVM> Children1 { get; set; }
	public DependencyFrameworkObservableCollection<ChildVM> Children2 { get; set; }

	public DelegateCommand AddToChildren1Command
	{
		get
		{
		return new DelegateCommand(() => Children1.Add(new ChildVM(Children1)));
		}
	}

	public DelegateCommand AddToChildren2Command
	{
		get
		{
		return new DelegateCommand(() => Children2.Add(new ChildVM(Children2)));
		}
	}

	public DelegateCommand UseLeftCommand
	{
		get
		{
			return new DelegateCommand(() => Children = Children1);
		}
	}

	public DelegateCommand UseRightCommand
	{
		get
		{
			return new DelegateCommand(() => Children = Children2);
		}
	}

	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 how a delegate points to the Collections' property, 
			//thereby allowing the collection to be swapped out.

			if (Children.Count == 0)
				return 0;

			return Children.Select(k => k.A1).Sum();
		}
	}

	private int _b2;
	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));
			}
		}
	}
}

3 thoughts on “PDFx – Property Dependency Framework – Part IX, Dynamic Collection Dependencies

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

  2. Pingback: PDFx – Property Dependency Framework – Part V, Simple Property Dependencies | //InterKnowlogy/ Blogs

  3. Pingback: PDFx – Property Dependency Framework – Part VI, External Property Dependencies | //InterKnowlogy/ Blogs

Leave a Reply

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