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:

SimpleCollectionDependency.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()
	{
		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));
			}
		}
	}
}

Last edited May 16, 2013 at 11:50 PM by KevinStumpf, version 3

Comments

No comments yet.