Multiple dialogs with WPF MaterialDesign and DialogHost

Veröffentlicht von

Using the Material Design for WPF I came across the dialogs. I wanted to show different dialogs in a DialoagHost. The first impression is, that only one dialog can be added to each dialog host. But how to show different dialogs.

In my example I want to display two different dialog type. An information message and an error message. The trick to do this, is using two data templates, which define the appearance of each dialog.

But first lets start with the MainWindow. We define the content of the MainWindow as DialogHost:

<materialDesign:DialogHost Identifier="RootDialog"
                       CloseOnClickAway="True">

The identifier is “RootDialog”. This ID can be used to open a dialog within this DialogRoot.

For the message type we define a common base message type our error and info message share.

public class NotificationMessage
{
    private string _message = "";
    private string _title = "";

    public string Message { get => _message; set => _message = value; }
    public string Title { get => _title; set => _title = value; }
}

From that I just derive two different classes for info and error:

public class ErrorNotificationMessage : NotificationMessage
{
    public ErrorNotificationMessage()
    {
        Title = "Error";
    }
}

public class InfoNotificationMessage : NotificationMessage
{
    public InfoNotificationMessage()
    {
        Title = "Info";
    }
}

So far, so simple. To show a message, I will call the DialogHost.Show method from code behind:

InfoNotificationMessage msg = new InfoNotificationMessage();
msg.Message = "Hello information";

await DialogHost.Show(msg, "RootDialog");

Simple enough! But before this does anything meaningful, we have to define the appearance of the dialog in a data template:

<Window.Resources>
  <ResourceDictionary>
    <!-- Dialog for errors -->
    <DataTemplate DataType="{x:Type model:ErrorNotificationMessage}">
    <StackPanel Margin="20">
      <Grid>
        <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"></ColumnDefinition>
        <ColumnDefinition Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <materialDesign:PackIcon Kind="Error"
               Height="48"
               Width="48"
               Margin="20, 25, 20, 20"
               Grid.Column="0" />
        <StackPanel Margin="20"
            Grid.Column="1"
            MinWidth="300">
        <TextBlock Text="{Binding Title}"
             Style="{StaticResource MaterialDesignTitleTextBlock}"></TextBlock>
        <TextBlock Text="{Binding Message}"
             Margin="0,20,0,0"></TextBlock>
        </StackPanel>
      </Grid>
      <Button Content="OK"
        Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"></Button>
    </StackPanel>
    </DataTemplate>

    <!-- Dialog for info -->
    <DataTemplate DataType="{x:Type model:InfoNotificationMessage}">
    <StackPanel Margin="20"
        Grid.Column="1"
        MinWidth="300">
      <TextBlock Text="{Binding Title}"
         Style="{StaticResource MaterialDesignTitleTextBlock}"></TextBlock>
      <TextBlock Text="{Binding Message}"
         Margin="0,10,0,20"></TextBlock>
      <Button Content="OK"
        Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"></Button>
    </StackPanel>
    </DataTemplate>
  </ResourceDictionary>
</Window.Resources>

We have two data templates, one for the information message and one for the error message. Depending on the object we provide for the Show method the corresponding dialog will be shown:

Download of the example project

2 Kommentare

    1. Sagen wir mal so, es gibt keinen einfachen MessageBox-Ersatz den man einfach aufrufen kann. Du musst mindestens das Template selbst bauen, dann kannst Du das als MessageBox-Ersatz verwenden.

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.