View Models

  • 2 minutes to read

The View Model is a part of an MVVM application responsible for the interaction between the two other parts: Model and View.

Base View Models

The DevExpress MVVM Framework contains base classes that you can use to create your View Models:

BindableBase
Implements the INotifyPropertyChanged interface and allows you to implement bindable properties.
ViewModelBase
A BindableBase descendant that offers commands, services, and interaction between View Models.

Generated View Models

The MVVM Framework allows you to produce boilerplate code for your View Models, so that you do not need to implement each command or property:

Runtime-generated POCO View Models
Use the ViewModelSource.Create method to create a descendant of your View Model class. The mechanism is based on the Reflection Emit and produces code at runtime.
View Models Generated at Compile Time
Use attributes to generate a View Model. The mechanism is based on the Source Generators and produces code at compile time.

You can find the requirements for both techniques in the table below:

POCO View Models generated at runtime View Models generated at compile time
C# v6+ v9+
.NET Framework v4.5.2+ v4.6.1+
.NET Core v3.0+ v3.0+

The following table summarizes the differences between View Models generated at runtime and compile time:

POCO View Models generated at runtime View Models generated at compile time
Execution time Runtime Compile time
Generated class Descendant class Partial class
Generated code access no Read-only .cs file
Debug access no yes
VB support yes no

Dependency Injection

To bind a view to a view model, create a MarkupExtension that resolves the correct ViewModel type:

public class DISource : MarkupExtension {
    public static Func<Type, object, string, object> Resolver { get; set; }

    public Type Type { get; set; }
    public object Key { get; set; }
    public string Name { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider) => Resolver?.Invoke(Type, Key, Name);
}

Register the resolver at the application startup:

protected override void OnStartup(StartupEventArgs e) {
    base.OnStartup(e);
    DISource.Resolver = Resolve;
}
object Resolve(Type type, object key, string name) {
    if(type == null)
        return null;
    if(key != null)
        return Container.ResolveKeyed(key, type);
    if(name != null)
        return Container.ResolveNamed(name, type);
    return Container.Resolve(type);
}

Specify the DataContext in XAML in the following manner:

DataContext="{common:DISource Type=common:CollectionViewModel}"

Examples

View Model Interaction