I am using an AppWindow in my UWP app. Most of the time things are good, but occasionally when I close the app window there is some strange behavior.
Occasionally, the app window does not seem to close properly. What I observe is that app window seems to close (the content of the app window is gone), but the title of the app window has moved to the main window title bar. After this happens, if I try to open a new app window, using appWindow.TryShowAsync(), it fails with the exception "Element not found. (Exception from HRESULT: 0x80070490)"
I do the app windows cleanup as shown in the Microsoft documentation and, most of the time, I can close an app window and open a new app window multiple times.
Any idea why it sometimes does not work?
PS In the documentation there is a note from Microsoft dated 07/19/2019 that says, "AppWindow is currently in preview. This means you can submit apps that use AppWindow to the Store, but some platform and framework components are known to not work with AppWindow." Now that we’re in the middle of 2020, is AppWindow still in “preview?”
Update 2020-07-15
As Faywang – MSFT suggested, I created a small test app to try to reproduce the problem. So far, I can’t reproduce the problem with the test app, but here’s an update with some more data.
I’ve been doing a lot of testing and I did discover that the problem occurs even less frequently with a release build of my app, versus a debug build. So, I’m almost ready to give up and chalk up the strange behavior to alpha particles coming from space in and flipping 1’s to 0’s, almost. :)
I discover that I can get the problem to occur in my app without the user doing any significant operations. That is, if I launch the app, bring up the app window, then close the app window, the problem can occur (after about 10 – 20 attempts). When I do that same sequence with my test app, I have not seen the problem occur, yet.
So, I still don’t have an answer, but I do have two new theories. The latest theory is that maybe my main page, and its associated Xaml, does not get initialized properly (and that’s why the app window has problems later). I say that because in my real app, I see these messages before the app window appears
onecoreuap\windows\wgi\winrt\display\displaycommon.cpp(411)\Windows.Graphics.dll!00007FFCE38B04B0: (caller: 00007FFCE38B01F5) ReturnHr(1) tid(6358) 80070490 Element not found.
onecoreuap\windows\wgi\winrt\display\displaycommon.cpp(411)\Windows.Graphics.dll!00007FFCE38B04B0: (caller: 00007FFCE38B01F5) ReturnHr(2) tid(6358) 80070490 Element not found.
onecoreuap\windows\wgi\winrt\display\displaycommon.cpp(411)\Windows.Graphics.dll!00007FFCE38B04B0: (caller: 00007FFCE38B017A) ReturnHr(3) tid(6358) 80070490 Element not found.
onecore\com\combase\objact\dllcache.cxx(4713)\combase.dll!00007FFCEB90964E: (caller: 00007FFCEB811D1D) ReturnHr(1) tid(6358) 80040111 ClassFactory cannot supply requested class
The first message appears when I show an image on the main page. The next three appear when I use a flyout menu to invoke the app window. I don’t see those messages when I invoke the app window in my test app. I had been ignoring those messages because the main page seems to work fine, and the flyout menu works fine, but maybe some damage has been done. When I search for theses messages on the web, they seem to be pretty non-specific and related to a lot of other failures that have nothing to do with App Windows.
Does anyone have an insight from those messages?
Another theory is that this main window / app window behavior has nothing to do with my code but is some sort of problem with Visual Studio 2019 grabbing different Windows dlls (like Windows.Graphics.dll) to build with my code. The real app has been built and rebuilt over the past few months, and with different versions of VS2019, but the test app was just built yesterday. I just updated to new version of VS2019, 16.6.4 I had been thinking that if I delete the bin and obj folders and then rebuild my app with the latest version of VS, there can’t be any residual effect of having been built with earlier versions.
Is that correct thinking?
One more thing. I discovered that when I close the app window and the odd behavior occurs on closing, the event ApplicationView.Consolidated has fired, and both IsAppInitiated and IsUserInitiated are false. That event “occurs when the window is removed from the list of recently used apps, or if the user executes a close gesture on it.”
Does that mean that Windows thinks the user is trying to close the main window when the user is actually trying to close the app window?
Update#2 2020-07-15
As Ivan Verges suggested, I’m posting some code. I’m posting this as an answer with a little wishful thinking. Maybe someone will see what’s wrong here and then I’ll edit it into an answer. :)
You’ll see that my code is mostly copied from the Microsoft example about “Show multiple views with AppWindow.”
Ivan also wondered if I had a service, or a background task, or other long lifetime data objects. The answer to that is no for services or background tasks. As far as other long lifetime data objects, I don’t keep those in my EditPage class (that’s used for the app window). I keep long lifetime objects in my in the MainPage class (that’s used for the main window) and just display those in the controls on the edit page. Here’s my code to create the app window (I call it the Edit window in my app). And the code that gets called when the window gets closed (by the user)
// helper fcn launches the Edit window
private async Task ShowEditAppWindow()
{
if (AppWindows.Count > 0)
{
MainFlyout.Hide();
return;
}
// Create a new window.
AppWindow appWindow = await AppWindow.TryCreateAsync();
// Create a Frame and navigate the Frame to a XAML-style Page object
Frame appWindowContentFrame = new Frame();
appWindowContentFrame.Navigate(typeof(EditPage));
// Attach the XAML content to the window
ElementCompositionPreview.SetAppWindowContent(appWindow, appWindowContentFrame);
// Add the new page to the Dictionary using the UIContext as the Key.
AppWindows.Add(appWindowContentFrame.UIContext, appWindow);
appWindow.Title = "Edit Window ";
// When the window is closed, be sure to release
// XAML resources and the reference to the window.
appWindow.Closed += (ss, ee) => AppWindow_Closed(ss, ee, appWindowContentFrame);
// try to show the Edit window
InEditState = false;
bool successShowing = false;
try
{
successShowing = await appWindow.TryShowAsync();
}
catch (Exception ex)
{
successShowing = false;
Debug.WriteLine("Failure showing Edit window. " + ex.Message);
}
if (successShowing)
{
InEditState = true;
}
else
{
// clean up attempted window
MainPage.AppWindows.Remove(appWindowContentFrame.UIContext);
appWindowContentFrame.Content = null;
appWindow = null;
InEditState = false; }
}
private void AppWindow_Closed(AppWindow sender, AppWindowClosedEventArgs args,
Frame appWindowContentFrame, AppWindow appWindow)
{
Debug.WriteLine("in AppWindow_Closed handler");
MainPage.AppWindows.Remove(appWindowContentFrame.UIContext);
appWindowContentFrame.Content = null;
appWindow = null;
InEditState = false;
// set a variable to indicate the appWindow just closed
EditWindowJustClosed = true;
// start timer to clear that indication
EditWindowJustClosedTimer.Start();
// always get show going after edit window closes
SlideTimer_Tick(null, null); // simulate timeout of the Slide timer
}