Search code examples
c#xamluwptemplate10

(UWP) Using ESC Key to Close ModalDialog


I'm displaying ModalDialog using sample code Busy.xaml in Template10 :

    public static void SetBusy(bool busy, string text = null)
    {
        WindowWrapper.Current().Dispatcher.Dispatch(() =>
        {
            var modal = Window.Current.Content as ModalDialog;
            var view = modal.ModalContent as Busy;
            if (view == null)
                modal.ModalContent = view = new Busy();
            modal.IsModal = view.IsBusy = busy;
            view.BusyText = text;
            modal.CanBackButtonDismiss = true;
        });
    }

I can close this dialog by using ALT+Left Arrow, but on most Desktop application pressing ESC key usually will also close popup or dialog.

I try to add code to handle KeyDown on Busy.xaml but this method never executed when I press ESC or any key.

     private void UserControl_KeyDown(object sender, KeyRoutedEventArgs e)
     {
         if (e.Key == VirtualKey.Escape)
         {
             e.Handled = true;
             SetBusy(false);
         }
     }

So, how to make this ModalDialog close when user press ESC key ?


Solution

  • You have to attach an event handler to the CharacterReceived event of the CoreWindow.

    Modify the SetBusy method:

    public static void SetBusy(bool busy, string text = null)
    {
        WindowWrapper.Current().Dispatcher.Dispatch(() =>
        {
            var modal = Window.Current.Content as ModalDialog;
            var view = modal.ModalContent as Busy;
            if (view == null)
                modal.ModalContent = view = new Busy();
            modal.IsModal = view.IsBusy = busy;
            view.BusyText = text;
            modal.CanBackButtonDismiss = true;
    
            // Attach to key inputs event
            var coreWindow = Window.Current.CoreWindow;
            coreWindow.CharacterReceived += CoreWindow_CharacterReceived;
        });
    }
    

    Where as the CoreWindow_CharacterReceived would look like this:

    private static void CoreWindow_CharacterReceived(CoreWindow sender,
                                                     CharacterReceivedEventArgs args)
    {
        // KeyCode 27 = Escape key
        if (args.KeyCode != 27) return;
    
        // Detatch from key inputs event
        var coreWindow = Window.Current.CoreWindow;
        coreWindow.CharacterReceived -= CoreWindow_CharacterReceived;
    
        // TODO: Go back, close window, confirm, etc.
    }