Closed daawaan4U closed 4 years ago
Override Screen.CanCloseAsync?
Ohh rightt. I just noticed I don't actually have to listen to the application-closing and just make sure that the active file will be saved everytime the viewmodel is going to be closed. OnClose() is enough, Thanks!
Hello again! I did what you suggested by overriding the CanCloseAsync()
(instead of the OnClose()
because I can't execute asynchronous operations inside OnClose()
). I was able to notify the user before the app closed through a call from WindowManager.ShowMessageBox()
. Unfortunately, I encountered some unexpected issues.
What I did was I called the RequestClose()
of the ShellViewModel from the Closing
event of the ShellView Window. In the child ViewModel of the ShellViewModel, I overrode the CanCloseAsync
where I called the WindowManager.ShowMessageBox()
and an additional asynchronous operation for saving the file. Unexpectedly, the CanCloseAsync()
was being called twice when I step through my code causing the MessageBox to display again and eventually throwing an exception:
InvalidOperationException: Cannot set Visibility to Visible or call Show, ShowDialog, Close, or WindowInteropHelper.EnsureHandle while a Window is closing.
at System.Windows.Window.VerifyNotClosing()
at System.Windows.Window.InternalClose(Boolean shutdown, Boolean ignoreCancel)
at System.Windows.Window.Close()
at Stylet.WindowManager.WindowConductor.<Stylet-IChildDelegate-CloseItem>d__6.MoveNext() in /_/Stylet/WindowManager.cs:line 372
...
It seems like showing a message box while the main window is closing doesn't work. An answer from stackoverflow mentions setting the Cancel
property of the CancelEventArgs
. However, the CancelEventArgs
is already handled within the WindowManager
so I think there's nothing I can do by just using user code only.
Just an update, I already fixed my issue. The cause of the CanCloseAsync()
being called twice was because I registered a RequestClose()
on the closing event of the Window while not being mindful enough that the WindowManager
already handles the closing of the RootViewModel's Window. Overriding only the CanCloseAsync()
of the child ViewModel was actually already enough. Thanks again!
Thanks for the update, glad you solved it!
I haven't found a way to listen to the closing of an application from a view model so that I can notify the user before the app will finally close (e.g. asking the user to save the active file before closing). I've been thinking of using the IEventAggregator to publish an application-closing event from the OnClose event of the bootstrapper to broadcast that the application will close and I will just subsribe the view model.
Hopefully, are there any existing methods in Stylet that I might have missed that can notify viewmodels about the lifetime of the application?
Framework: .NET Core 3.1 Visual Studio version: 16.6.0 Stylet version: 1.3.3