MaterialDesignInXamlToolkit icon indicating copy to clipboard operation
MaterialDesignInXamlToolkit copied to clipboard

DialogHost IsLoaded but not exactly

Open jbooth88 opened this issue 10 months ago • 3 comments

Bug explanation

I've uploaded a sample project illustrating the issue.

When trying to get a WPF window to open a view using DialogHost on initial startup/show, I noticed that the DialogHost.Show method throws an exception even though the DialogHost instance IsLoaded property was true. I am thinking the DialogHost is loaded but not yet registered in the LoadedInstances HashSet by the time the Window.IsLoaded event triggers.

https://github.com/jbooth88/DialogHostStartupExample

Looks like IsLoaded property is coming from FrameworkElement, so my guess here is that it's not the correct value to identify whether or not the DialogHost is fully initialized. I am not sure of the best way to solve this problem.

Version

5.2.1

jbooth88 avatar Mar 04 '25 18:03 jbooth88

FYI: As far as I can tell the problem is that the Show method is called before the Loaded event of the DialogHost is raised. Therefore the dialoghost instance has not yet been added to the LoadedInstances hashset.

Executing the logic in the Onloaded method when the Initialized event is raised fixes this problem. I am however not confident that this is a suitable fix, because the DialogHost is quite a large class and it could possibly break something else. https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/ae59e318a251ef2f6349eceb7a2a544658a9911a/src/MaterialDesignThemes.Wpf/DialogHost.cs#L288

public DialogHost()
{
-   Loaded += OnLoaded;
+   Initialized += OnLoaded;
    Unloaded += OnUnloaded;

    CommandBindings.Add(new CommandBinding(CloseDialogCommand, CloseDialogHandler, CloseDialogCanExecute));
    CommandBindings.Add(new CommandBinding(OpenDialogCommand, OpenDialogHandler));
}

Edit: @jbooth88 if applicable and you need a quick & dirty fix you can just listen for the Loaded event on the DialogHost like so:

public MainWindow()
{
    InitializeComponent();
    myDialogHost.Loaded += MyDialogHost_Loaded;
}
private async void MyDialogHost_Loaded(object sender, RoutedEventArgs e) => await DialogHost.Show("test content", "RootDialog");

corvinsz avatar Mar 11 '25 17:03 corvinsz

That is covered in "Scenario 3" in the sample project I provided. It works only if the DialogHost was not already loaded/initialized prior to the window constructor call (which I admit won't be a problem for most users).

jbooth88 avatar Mar 11 '25 18:03 jbooth88

@corvinsz can you please help me and check my issue as i am not expert in material design toolkit structure ? https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/issues/3824

AmeerMansour avatar Mar 29 '25 02:03 AmeerMansour