Skip to content
Thomas Freudenberg edited this page Feb 13, 2015 · 4 revisions

TinyLittleMvvm provides the classes DialogViewModel and DialogViewModel<TResult>. The first class is the base class for view models of dialogs which do not have an result but simply close. The latter allows the implementor to specify the return type of the dialog.

Both classes have a Task property, allowing the code to wait for the dialog to close. The view model itself closes the dialog by calling Close, which completes the Task property.

Example:

The view

First, the view of the dialog, SampleDialogView.xaml, inherits from MahApps.Metro's BaseMetroDialog:

<Dialogs:BaseMetroDialog
  x:Class="TinyLittleMvvm.Demo.Views.SampleDialogView"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:ViewModels="clr-namespace:TinyLittleMvvm.Demo.ViewModels"
  xmlns:Dialogs="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
  mc:Ignorable="d"
  d:DesignHeight="300" d:DesignWidth="300"
  d:DataContext="{d:DesignInstance ViewModels:SampleDialogViewModel}"
  Title="Sample Dialog">
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition Width="1000*" MaxWidth="200" />
      <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Label
      Grid.Row="0" Grid.Column="0"
      Content="_Enter text:"
      Margin="0 4"/>
    <TextBox
      Grid.Row="0" Grid.Column="1"
      Text="{Binding Text}"
      Margin="0 5"/>

    <StackPanel
      Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3"
      Orientation="Horizontal" HorizontalAlignment="Right"
      Margin="0 5 0 10">
      <Button Command="{Binding OkCommand}" Content="OK" Margin="0 0 10 0" Width="100" IsDefault="True"/>
    </StackPanel>

  </Grid>
</Dialogs:BaseMetroDialog>

This defines a layout with a text box (bound to Text), where the user can enter some text, and an "OK" button (bound to OkCommand).

The view model

The corresponding view model provides the bound properties Text and OkCommand.

public class SampleDialogViewModel : DialogViewModel<string> {
    private readonly ICommand _okCommand;
    private string _text;

    public SampleDialogViewModel() {
        _okCommand = new RelayCommand(OnOk, CanOk);
        _text = String.Empty;
    }

    public string Text {
        get { return _text; }
        set {
            if (_text != value) {
                _text = value;
                NotifyOfPropertyChange(() => Text);
            }
        }
    }

    public ICommand OkCommand {
        get { return _okCommand; }
    }

    private bool CanOk() {
        return !HasErrors;
    }

    private void OnOk() {
        Close(Text);
    }
}

When the OkCommand is invoked, OnOk calls the base class' Close, passing the content of the text box.

Showing the dialog

To display the dialog, you need an instance of IDialogManager (by injection) and call

var dialogViewModel = new SampleDialogViewModel();
var text = await _dialogManager.ShowDialogAsync(dialogViewModel);

or, if you don't need to initialize the model,

var text = await _dialogManager.ShowDialogAsync<SampleDialogViewModel, string>();
Clone this wiki locally