Among client applications, this problem is the most common among Single Page applications. Experienced developers often split a View into several Views as sub-Views. These jobs require a lot of practical knowledge.

A Prototype Chain for JavaScript

When the word “sharing” is first mentioned, the first thing that comes to my mind is “inheritence”. Because you are a child of a parent, so sharing essentially means building an “inheritence chain”, and this is known in JavaScript as a “Prototype Chain”.

So how is this implemented in JavaScript? To ensure this, a built-in attribute is applied “proto”, how to implement the inheritence chain between ViewModels is shown below:

ViewModelChain UML

Creating Inheritance Relationship for ViewModel

After the above analysis, when we look at the implementation of “proto” in the JavaScript language, we add a ParentViewModel attribute to the ViewModelBase to represent the parent.

public class ViewModelBase
{
    public ViewModelBase ParentViewModel { get; set; }
	//...
}

Now let’s see how we access the data in the parent ViewModel in WPF:

Binding = "{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorType = {x:Type Window}}, Path=DataContext.ParentViewModelProperty}

When we look at the usage above, a FindAncestor method is used to get data from a parent object according to the object specified with AncestorType. Starting from here, we are preparing an extension method for our ViewModel.

    public static IEnumerable<T> Ancestors<T>(this ViewModelBase origin) where T : ViewModelBase
    {
        if (origin==null)
        {
            yield break;
        }
        var parentViewModel = origin.ParentViewModel;
        while (parentViewModel!=null)
        {
            var castedViewModel = parentViewModel as T;
            if (castedViewModel != null)
            {
                yield return castedViewModel;
            }
            parentViewModel = parentViewModel.ParentViewModel;
        }

    }

Thanks to this method, we can get the data of the object in the upperclass with the following usage.

var ancestors = this.Ancestors<FaceBoxViewModel>();

Our app has now become more intuitive. According to the inheritance chain, ParentViewModel’s data can be easily accessed with SubViewModel.

SharingData UML