1

How to intercept app_closing or app_entering_background in WinUi 3 app.

In UWP apps we do have Application_EnteredBackground event , in which we can intercept app close, we use GetDeferral() to save data .

Is there any same kind of event in WinUI 3 apps, I need to save data on app close, or entering background.

Tried window_VisibilityChanged and window_Closed events, but not able to use GetDeferral().

Kindly help

Thanks in advance .

Noorul

Noorul
  • 873
  • 2
  • 9
  • 26
  • In winui3, I also found [AppWindow.Closing](https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.windowing.appwindow.closing?view=windows-app-sdk-1.1), but there is no `GetDeferral()` . If you don't use `GetDeferral()`, can you save data normally in the OnClosing event? – Junjie Zhu - MSFT Sep 13 '22 at 08:10
  • If you are in production, try what Junjie Zhu is suggesting. You also can use the **Closed** event from **MainWindow**. If you are not in production, try the [Experimental](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/preview-experimental-install?tabs=vs-2022-17-1) channel. You'll find **GetDeferral()** there. – Andrew KeepCoding Sep 13 '22 at 08:42
  • Hi , how to register for AppWindow.Closing event ? I mean how to get AppWindows in code behind, can you refer any code ? @JunjieZhu-MSFT – Noorul Sep 13 '22 at 09:21

1 Answers1

0

Here is my test code for your reference, you can intercept the closing event.

(closing is executed before closed)

public sealed partial class MainWindow : Window
{
    private AppWindow _appWindow;

    public MainWindow()
    {
        this.InitializeComponent();
        
        this.Closed += OnClosed;

       _appWindow = GetAppWindowForCurrentWindow();
       _appWindow.Closing += OnClosing;
    }
   
    private void OnClosed(object sender, WindowEventArgs e)
    {
        string btnText = myButton.Content.ToString();
    }


    private async void OnClosing(object sender, AppWindowClosingEventArgs e)
    {

       string btnText =  myButton.Content.ToString();

       e.Cancel = true;     //Cancel close
                            //Otherwise, the program will not wait for the task to execute, and the main thread will close immediately

       //await System.Threading.Tasks.Task.Delay(5000); //wait for 5 seconds (= 5000ms)

       Func<bool> funcSaveData = () =>
       {

           //perform operations to save data here
            return true;
       };

       var funResult = await Task.Run(funcSaveData);

       this.Close();   //close
    }

    
    private AppWindow GetAppWindowForCurrentWindow()
    {
        IntPtr hWnd = WindowNative.GetWindowHandle(this);
        WindowId myWndId = Win32Interop.GetWindowIdFromWindow(hWnd);
        return AppWindow.GetFromWindowId(myWndId);
    }

    private void myButton_Click(object sender, RoutedEventArgs e)
    {
        myButton.Content = "Clicked";
    }
}
Junjie Zhu - MSFT
  • 2,086
  • 1
  • 2
  • 6
  • Thanks , this is really helpful. But I am trying to do async operation to save data, I don't find any possibility to achieve that. Is there any possibility to hold the app close for 1 or 2 seconds (or hold app close till my async task completes) ? – Noorul Sep 13 '22 at 13:15
  • Please see my modification on function `Onclosing`. You need to cancel the execution of Onclosing first, then execute the save data operation according `sync-and-await`, and use close() to close the program. – Junjie Zhu - MSFT Sep 14 '22 at 02:44