Skip to content

πŸ“ View Models

Marc Rousavy edited this page Jun 8, 2020 · 7 revisions

Every ViewModel needs to implement the ViewModel class:

class LoginViewModel : ViewModel
{
    ...
}

The ViewModel base class inherits from ObservableObject but provides additional functionality to a plain ObservableObject (see: View Models or Observable Objects πŸ“–).

Using the ObservableObject base class Set function allows for quick notifying properties:

class LoginViewModel : ViewModel
{
    private User _user;
    public User User
    {
        get => _user;
        set => Set(ref _user, value);
    }
}

If you are using ReSharper you can define a notify-property-changed-property template πŸ“–.

You can also force a PropertyChanged invocation by using the Notify function:

public string UserString => $"Mr./Mrs. {User}";

public User User
{
    get => _user;
    set
    {
        Set(ref _user, value);
        Notify(nameof(UserString));
    }
}

See also: View Model Locator πŸ“–

Data Templates

You can bind your ViewModel to a given View by defining a DataTemplate in a resource dictionary (e.g. App.xaml):

<DataTemplate DataType="{x:Type login:LoginViewModel}">
    <login:LoginView />
</DataTemplate>

WPF will show a LoginView with a set DataContext when any control's Content property is set to a LoginViewModel instance

<Window ...>
    <UserControl Content="{Binding CenterContent}" />
</Window>
class MainViewModel : ViewModel
{
    private object _centerContent;
    public object CenterContent
    {
        get => _centerContent;
        set => Set(ref _centerContent, value);
    }

    private void ShowLoginPage()
    {
        // Set content of UserControl to a ViewModel
        CenterContent = new LoginViewModel();
    }
}

As you can see, no UI code is required as WPF will automatically notice that the CenterContent changed, and look up the corresponding View.