Create WPF View Models at compile time with MVVM Code Generator

WPF Team Blog
03 June 2021

As you may already know, the DevExpress WPF product suite (v21.1) now includes a View Model Code Generator. This Code Generator allows you to generate boilerplate code for your View Model at compile time.

Microsoft introduced Source Generators in C# 9. You can use the Source Generator to analyze user code and generate new source files during compilation. We leveraged this Microsoft technology to help you develop View Models and immediately obtain generated code.

Note that the DevExpress MVVM Framework already includes multiple ways to create View Models (such as POCO View Models based on Emit Reflection to create View Models at runtime).

This new method offers you a number of important benefits:

  • You can view generated code and debug in Visual Studio.
  • Generated code is produced during compilation and is available at application startup. Accordingly, this new approach improves startup performance.

Create a View Model with Generated Code

To produce a full-fledged View Model, you need to define a stub View Model class that specifies the required logic. The View Model Code Generator analyzes your implementation and applied attributes to generate the final View Model class, with all the required boilerplate code. Consider the following example: How to: Use View Models Generated at Compile Time

Base View Model

using DevExpress.Mvvm.CodeGenerators;

[GenerateViewModel]
partial class ViewModel {
    [GenerateProperty]
    string username;
    [GenerateProperty]
    string status;

    [GenerateCommand]
    void Login() => Status = "User: " + Username;
    bool CanLogin() => !string.IsNullOrEmpty(Username);
}

Generated View Model

The Code Generator inspects the base View Model and produces a partial class that complements your implementation with the following boilerplate code:

partial class ViewModel : INotifyPropertyChanged {
    public event PropertyChangedEventHandler? PropertyChanged;

    protected void RaisePropertyChanged(PropertyChangedEventArgs e) => PropertyChanged?.Invoke(this, e);

    public string? Username {
        get => username;
        set {
            if(EqualityComparer<string?>.Default.Equals(username, value)) return;
            username = value;
            RaisePropertyChanged(UsernameChangedEventArgs);
        }
    }

    public string? Status {
        get => status;
        set {
            if(EqualityComparer<string?>.Default.Equals(status, value)) return;
            status = value;
            RaisePropertyChanged(StatusChangedEventArgs);
        }
    }

    DelegateCommand? loginCommand;
    public DelegateCommand LoginCommand {
        get => loginCommand ??= new DelegateCommand(Login, CanLogin, true);
    }

    static PropertyChangedEventArgs UsernameChangedEventArgs = new PropertyChangedEventArgs(nameof(Username));
    static PropertyChangedEventArgs StatusChangedEventArgs = new PropertyChangedEventArgs(nameof(Status));
}

Refer to the following article for more information on how to prepare your project, apply attributes, generate properties, commands, implement interfaces, and specify custom names: View Models Generated at Compile Time.

Method – The Way Forward

The best path forward will be driven by each individual WPF project:

  • If you're using the latest C# version and .NET Framework v4.6.1+ or .NET Core v3.0+, consider View Models Generated at Compile Time.
  • If you want to maintain full control over your View Model, you can inherit your View Model from Base Classes.
  • If your project does not meet the requirements above or you're using Visual Basic (and still wish to avoid boilerplate code), the POCO View Models are a good option.

Feedback

Should you have any questions or require additional information on View Models, please post your comment below. If you’re using/planning to use an MVVM Framework, please take a moment to answer the following survey question:

Free DevExpress Products - Get Your Copy Today

The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the DevExpress Support Center at your convenience. We'll be happy to follow-up.
No Comments

Please login or register to post comments.