-
Notifications
You must be signed in to change notification settings - Fork 22
Reactive Library Overview
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.
- Log4Net 2.0.8
- System.Reactive 4.1.0
- Unity 5.8.11
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);
}
}
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);
}
}
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);
}
}