Skip to content

Reactive Library Overview

andyb1979 edited this page Sep 19, 2018 · 1 revision

The SciChart.UI.Reactive library provides observable viewmodels which combine INotifyPropertyChanged event notifications for WPF, and Reactive IObservable streams for observing individual, or combinations of properties.

NuGet Package

Dependencies for SciChart.UI.Reactive

  • Log4Net 2.0.8
  • System.Reactive 4.1.0
  • Unity 5.8.11

Key Types Included in SciChart.UI.Reactive

ViewModelBase

A ViewModel type which implements INotifyPropertyChanged only, no reactive, and no Finalizer. Supports dynamic properties for get/set (more on this below).

e.g.

// Lightweight viewmodel which does not implement the Finalizer pattern, 
// does not support Rx and is suitable for rapid instantiation e.g. ListBoxItem ViewModels or search results
public class MyLightweightViewModel : ViewModelBase
{
	// A boolean property 
	public bool AProperty
	{
		// Backing fields mimicked by dictionary. 
		get => GetDynamicValue<bool>();
		// Setting sets the value and raises INotifyPropertyChanged for property "AProperty"
		set => SetDynamicValue(value);
	}
}

ObservableObjectBase

A ViewModel type which implements INotifyPropertyChanged, IDisposable, IObservableObject the Finalizer Pattern and supports PropertyChanged notifications via Rx (Reactive Extensions)

e.g.

// Viewmodel which which implements INotifyPropertyChanged, IObservableOject, IDisposable
// Supports Rx and can subscribe to property changed notifications on any property 
public class MyReactiveViewModel : ObservableObjectBase
{
	public MyReactiveViewModel()
	{
		// WhenPropertyChanged returns IObservable<bool> for property AProperty
		this.WhenPropertyChanged(x => x.AProperty)
			// Subscribe to the observable
			.Subscribe(newValue => Console.WriteLine($"NewValue is {newValue}!"))
			// Ensure disposable of subscription with parent
			.DisposeWith(this);
	}

	// A boolean property 
	public bool AProperty
	{
		// Backing fields mimicked by dictionary. 
		get => GetDynamicValue<bool>();
		// Setting sets the value and raises INotifyPropertyChanged for property "AProperty"
		// Also pushes a new value through the ObservableObjectBase.PropertyChangedSubject 
		set => SetDynamicValue(value);
	}
}

ViewModelWithTraitsBase

This type builds upon ObservableObject by providing traits - a neat way to store complex behaviours related to one or more operations in the ViewModel in one place.

Dependencies to the Traits are automatically injected if they are registered in a UnityContainer provided by ViewContext.Container.

public class Program
{
	static void Main()
	{
		// For traits to work they expect ViewContext.Container to be a UnityContainer instance
		var container = new UnityContainer();
		ViewContext.Container = container;

		// and dependent types to be registered. 
		// See SciChart.UI.Bootstrap for how to auto-register using the 
		// [ExportType] attribute 
		container.RegisterType<ISomeDependency, SomeDependency>();
	}
}


public interface ISomeDependency
{
	void WriteLine(string line);
}

// Here's my dependency, which gets auto-injected into the constructor of MyTrait 
public class SomeDependency : ISomeDependency
{
	public void WriteLine(string line)
	{
		Console.WriteLine(line);
	}
}

// The trait is a class for putting groups of behaviours with dependencies specified by Unity in one place
// It is attached to the ViewModel using the WithTrait<T> function 
public class MyTrait : ViewModelTrait<MyReactiveViewModelWithTraits>
{
	public MyTrait(MyReactiveViewModelWithTraits target, ISomeDependency someDependency) : base(target)
	{
		// WhenPropertyChanged returns IObservable<bool> for property AProperty
		Target.WhenPropertyChanged(x => x.AProperty)
			// Subscribe to the observable
			.Subscribe(newValue => someDependency.WriteLine($"NewValue is {newValue}!"))
			// Ensure disposable of subscription with parent
			.DisposeWith(this);
	}
}

// Viewmodel which which implements INotifyPropertyChanged, IObservableOject, IDisposable
// Supports Rx and can subscribe to property changed notifications on any property 
public class MyReactiveViewModelWithTraits : ViewModelWithTraitsBase
{
	public MyReactiveViewModelWithTraits()
	{
		this.WithTrait<MyTrait>();           
	}

	// A boolean property 
	public bool AProperty
	{
		// Backing fields mimicked by dictionary. 
		get => GetDynamicValue<bool>();
		// Setting sets the value and raises INotifyPropertyChanged for property "AProperty"
		// Also pushes a new value through the ObservableObjectBase.PropertyChangedSubject 
		set => SetDynamicValue(value);
	}
}