Search code examples
c#wpfxamldialog

Show Initial Dialog before MainWindow in WPF Material Design


I am using MaterialDesign for my WPF project which downloads json from remote server and parse. Before showing MainWindow, I want to open initial loading dialog to show how much loading is completed.

MainWindow.xaml

<materialDesign:DialogHost Identifier="RootDialog" CloseOnClickAway="False">
    <TextBlock Text="Loading Completed." />
</materialDesign:DialogHost>

MainWindowViewModel.cs

public class MainWindowViewModel: BaseViewModel
{
   public MainWindowViewModel(Window mWindow) {
      ...
      ShowInitialDialog();
      ...
   }
   private async void ShowInitialDialog()
   {
      var view = new LoadingDialog();
        
      //show the dialog
      var result = await DialogHost.Show(view, "RootDialog", null, null);

      //check the result...
      Debug.WriteLine("Dialog was closed, the CommandParameter used to close it was: " + (result ?? "NULL"));
    }
}

LoadingDialog.xaml

<UserControl 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:wpf="clr-namespace:MaterialDesignThemes.Wpf;assembly=MaterialDesignThemes.Wpf"
             mc:Ignorable="d">
    <StackPanel Orientation="Vertical" VerticalAlignment="Center" Margin="10">
        <ProgressBar Width="60" Height="60" Margin="16"
                     Style="{DynamicResource MaterialDesignCircularProgressBar}"
                     IsIndeterminate="True"
                     Value="33"/>
        <TextBlock Text="{Binding Notification}" HorizontalAlignment="Center"></TextBlock>
    </StackPanel>
</UserControl>

But when I ran the code, it shows error "DialogHost Instance not exist".

How do I get to know when the "RootDialog" DialogHost is instatiated?


Solution

  • Wait intil the DialogHost instance in the window has been loaded:

    public class MainWindowViewModel : BaseViewModel
    {
        public MainWindowViewModel(Window mWindow)
        {
            mWindow.rootDialog.Loaded += (s, e) => ShowInitialDialog();
        }
    
        private async void ShowInitialDialog()
        {
            var view = new LoadingDialog();
    
            //show the dialog
            var result = await DialogHost.Show(view, "RootDialog", null, null);
    
            //check the result...
            Debug.WriteLine("Dialog was closed, the CommandParameter used to close it was: " + (result ?? "NULL"));
        }
    }
    

    XAML:

    <materialDesign:DialogHost x:Name="rootDialog" x:FieldModifier="internal" 
                               Identifier="RootDialog" />
    

    As a side note, a view model having a strong reference to a window breaks the MVVM pattern.