2

I have a navigation view pattern in UWP app with a "navigation root" page hosting a frame for child pages. If I call a ContentDialog from a child page, I can still access objects in the master page if I use keyboard shortcuts. This can easily result in an app crash if another content dialog is opened.

How can I make ContentDialog truly modal?

Project demonstrating the issue can be found here: https://github.com/under3415/NavigationApp

In a nutshell, create two pages, one hosting the other in a frame

<Frame Grid.Row="1" x:Name="RootContentFrame"/>

In a master page, have a Button or another object with AccessKey defined. In a child page, call a ContentDialog. While content dialog is open press ALT key and then the access key. Even though the modal dialog is open, the object behind fires.

under
  • 2,519
  • 1
  • 21
  • 40

1 Answers1

1

In a master page, have a Button or another object with AccessKey defined. In a child page, call a ContentDialog. While content dialog is open press ALT key and then the access key. Even though the modal dialog is open, the object behind fires.

When the ContentDialog show, it will block interactions with the app window until being explicitly dismissed. But it could not block access keys, because are keyboard shortcuts that improve the usability and the accessibility of your Windows applications by providing an intuitive way for users to quickly navigate and interact with an app's visible UI through a keyboard instead of a pointer device (such as touch or mouse).

For your scenario, we suggest make event to detect Dialog show or not then set root page IsEnable true or false.

Make an Action in your app class

public static Action<bool> IsDialogOpen;

Detect Dialog open or close.

private async void Button_Click(object sender, RoutedEventArgs e)
{

    ContentDialog dialog = new ContentDialog
    {
        Content = "Press ALT, then C or V",
        Title = "Non Modal Dialog",
        PrimaryButtonText = "OK"
    };

    dialog.Opened += Dialog_Opened;
    dialog.Closed += Dialog_Closed;
    _ = await dialog.ShowAsync();


}

private void Dialog_Closed(ContentDialog sender, ContentDialogClosedEventArgs args)
{

    App.IsDialogOpen(false);
}

private void Dialog_Opened(ContentDialog sender, ContentDialogOpenedEventArgs args)
{

    App.IsDialogOpen(true);
}

Disable or Enable Root page base dialog open or not.

public NavigationRoot()
{
    this.InitializeComponent();
    App.IsDialogOpen = (s) =>
    {
        this.IsEnabled = s ? false : true;
  
    };
}
Nico Zhu
  • 32,367
  • 2
  • 15
  • 36
  • Hi, this works for the AccessKey, but does not work for KeyDown events. So user can still interact with the keyboard. – under Mar 23 '21 at 21:31
  • KeyDown event? could you share more detail about your scenario? – Nico Zhu Mar 24 '21 at 01:22
  • I have a few `private void CoreWindow_KeyDown(CoreWindow sender, KeyEventArgs args)` events to let user utilize keyboard shortcuts. e.g. use bumper button in xbox to change menu and the like. These still fire while the dialog box is open. they are not disabled with `this.IsEnbaled = false` – under Mar 24 '21 at 01:41
  • Base on above solution, you could unregister CoreWindow KeyDown event during dialog display. `Window.Current.CoreWindow.KeyDown -= CoreWindow_KeyDown;` – Nico Zhu Mar 24 '21 at 01:51
  • 1
    Everywhere around the application every time a dialog box is opened anywhere? Just because the ContentDialog is not modal as advertised? Can Microsoft not fix ContentDialog instead? – under Mar 24 '21 at 01:54
  • @NicoZhu-MSFT Hii, I have issue that if I navigate on page then there is 2-3 second delay to show the content dylog and between that gap we can click on screen. and If I click on screen before showing content dylog then screen stuck there like white screen. Any solution ? – Shashank Singh Apr 09 '22 at 04:54