I've been working almost exclusively in WPF/Prism using Unity and the MVVM pattern for about a year now. I've had pretty good success in establishing a shell, several modules, and lots of cool stuff like scoped RegionManagers and shell-hosted common popups.
I came across something today that has me really scratching my head: Cannot set Owner property to a Window that has been closed.
I have a requirement to periodically check for updates to assemblies, prompt the user to restart the application, then handle that in the shell's ViewModel. I'm doing that with a bootstrapper.Run()
, and in the bootstrapper
is a method that kills all windows. Boom, window that has been closed.
The error makes sense (and is pretty obvious), but I can't seem to remedy the issue. In Prism 6.2
, this (and perhaps more/less) was introduced:
if (AssociatedObject != null)
wrapperWindow.Owner = Window.GetWindow(AssociatedObject);
According to the stack trace, this is what is causing it to fail, because the PopupWindowAction
thinks it's Owner
is the now-closed Window
(though it's worth noting this is new functionality and wasn't tested < 6.2). I can't seem to find a way to re-instantiate it or Set
the Owner
(or something along those lines) -- or even what should happen here.
I'm firing this PopupWindowAction
via an InteractionRequestTrigger
, and all of that just opens a custom UserControl
. Also, all of this happens on another thread, so I have to go back to the primary Dispatcher
to find my scoped InteractionService
(which basically fires an INotification
):
Application.Current.Dispatcher.Invoke(() =>
{
var dialogResponse = InteractionService.ShowDialog(...
//...
My question is: can the popup not find it's parent because it's closed, or because it's now on a separate thread? Beyond that, is this a reasonable thing to be talking about or is there a better solution to my users' requirements?
This is definitively because the owner window is closed, has you said the dispatcher resolves the cross thread problem.
I don't know if I totally get it but… If you are unloading all modules but keeping your shell open I would suggest you to add an InteractionRequestTrigger to your shellview and create a composite command to raise it from your module