Search code examples
c#showdialogdialogresult

DialogResult Error in a Modal Window


Okay, this one will be a fun one. I am building an authentication flow in my application. My application will open a modal window with a webbrowser element and browse to the auth URL. Then it wil monitor the URL changes of the webbrowser element for a specific string. When it finds the string, it does it's work to retrieve the access code, closes the window and then returns the code to the parent. My code is as follows:

The modal window:

public partial class Browser : Window
{
    private string code = "";
    private Uri navi;

    public TwitchBrowser(Uri url)
    {
        InitializeComponent();
        this.navi = url;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        webBrowser.Navigate(this.navi);
        webBrowser.Navigating += webBrowser_Navigating;
    }

    void webBrowser_Navigating(object sender, NavigatingCancelEventArgs e)
    {
        if (e.Uri.ToString().Contains("?code="))
        {
            this.code = e.Uri.ToString().Split('?')[1].Split('&')[0].Replace("code=", "");
            this.DialogResult = true;
        }
    }

    public string result
    {
        get { return code; }
    }
}

The call from the parent:

string url = ...

Browser browser = new Browser(new Uri(url));
browser.Owner = parent;

if (browser.ShowDialog() == true)
{
    password.Password = browser.result;
    ...
}

And of course, the error I get:

DialogResult can be set only after Window is created and shown as dialog.

The interesting thing is, the app WORKS! It gets the code and stores it in the password field as it's supposed to. So whats the point of the error? I mean, I know I can suppress it with a Try-Catch; but I'm afraid its the root of a larger problem.


Solution

  • You original code had a race condition in there. You were navigating in the creation of browser. The navigation complete could be fired before you called ShowDialog().

    Instead stash away the url in a private variable and setup the WebBrowser in your Loaded event.

    Now that you have fixed that, I am guessing that you want the Nagivated event instead of the Navigating event to check the returned URI.

    It is still interesting that the Navigating event gives that error. I was able to reproduce it with a button click on the form, so I know the form is completely shown at that point.