Search code examples
c#uwpwin-universal-appwindows-10-universalwindows-10-mobile

Windows 10 UWP MessageDialog calls method twice after awaiting result


didn't know really the best way to describe the issue in the title. I have an Windows 10 UWP. All I am basically trying to do is check when the user selects another text box, that the previous one is not empty. In other words, it would be similar to a login field where I want them to enter the username first before password and as such, if they select to put focus in the password field while leaving username blank, I pop up a message to warn them of this and force focus back to the username field. Here is the code I have:

    private async void TbPassword_GotFocus(object sender, RoutedEventArgs e)
    {
        if (string.IsNullOrEmpty(tbUser.Text))
        {
            var md = new MessageDialog("Please specify a user first. ",
                "Enter UserName");
            md.Commands.Add(new UICommand("Okay")
            {

            });

            var result = await md.ShowAsync();

            if (result.Label == "Okay")
            {
                tbUser.Focus(FocusState.Programmatic);
            }
        }
        else
        {
            preCheckUser();
        }
   }

The problem I am having is that the TbPassword_GotFocus gets called twice each time. When setting breakpoints, here is what I see happens.

  1. When I first change focus, the method gets called as it should and it gets to the line

      var result = await md.ShowAsync();
    

And it stops and waits there as I think it should, until I select "Okay" on the message dialog.

  1. I then select "Okay" on the message dialog and the whole method is called again from the beginning. This causes the message box to show again, a second time.

  2. While that in itself is undesirable, after that I will either intermittently get an exception such as this one:

Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

OR it will work as expected the second time (if I did not get the above exception) and the message box will go away, leaving me with focus in the field I want, for the user.

So, the root cause is the method getting called twice, first when I do lose focus as expected but then again after I have clicked "Okay" and the await is done.

Any ideas why this is happening?

Thanks!


Solution

  • When you show the message box, the password box loses focus. When the message box is closed, the password box does then receive focus again, triggering the event.

    There are several approaches to solving this.

    Easiest is probably to set focus to the user input box before showing the message box.

    private async void TbPassword_GotFocus(object sender, RoutedEventArgs e)
    {
        if (string.IsNullOrEmpty(tbUser.Text))
        {
            tbUser.Focus(FocusState.Programmatic);
            var md = new MessageDialog("Please specify a user first. ",
                "Enter UserName");
            md.Commands.Add(new UICommand("Okay")
            {
    
            });
    
            await md.ShowAsync();
        }
        else
        {
            preCheckUser();
        }
     }