When you are trying to modify UI on the DotNetBrowser event, you can see System.InvalidOperationException with the description: "Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on.".


Cause:

The current version of DotNetBrowser fires its events through the separate threads and does not use the main thread for this purpose.


Solution:

To modify UI on the DotNetBrowser event it is necessary to pass execution to the main UI thread. This can be done via Invoke and BeginInvoke in WinForms or Dispatcher.Invoke and Dispatcher.BeginInvoke in WPF. The Control.InvokeRequired property (WinForms) or the Dispatcher.CheckAccess() call (WPF) can be used to check if it is necessary to pass the execution.


The following code samples demonstrate how to get access to UI from another thread.


WinForms

C#

BrowserView browserView = new WinFormsBrowserView(BrowserFactory.Create());            
browserView.Browser.FinishLoadingFrameEvent +=
    delegate (object sender1, FinishLoadingEventArgs finishLoadEvent)
{
    if (finishLoadEvent.IsMainFrame)
    {
        if (InvokeRequired)
        {
            BeginInvoke(new Action(() =>
            {
                this.Text = finishLoadEvent.Browser.URL;
            }));
        }
        else
        {
            this.Text = finishLoadEvent.Browser.URL;
        }
    }
};
browserView.Browser.LoadURL("teamdev.com");

VB.NET

Public Sub New()
    Dim browserView As BrowserView = New WinFormsBrowserView()
    AddHandler browserView.Browser.FinishLoadingFrameEvent, AddressOf Browser_FinishLoadingFrameEvent
    browserView.Browser.LoadURL("teamdev.com")
End Sub

Private Sub Browser_FinishLoadingFrameEvent(sender As Object, e As FinishLoadingEventArgs)
    If e.IsMainFrame Then
        If Me.InvokeRequired Then
            BeginInvoke(Sub()
                            Me.Text = e.Browser.URL
                        End Sub)
        Else
            Me.Text = e.Browser.URL
        End If
    End If
End Sub


WPF

C#

BrowserView browserView = new WPFBrowserView(BrowserFactory.Create());
browserView.Browser.FinishLoadingFrameEvent +=
    delegate (object sender, FinishLoadingEventArgs e)
    {
        if (e.IsMainFrame)
        {
            if (!Dispatcher.CheckAccess())
            {
                Dispatcher.Invoke(new Action(() =>
                {
                    this.Title = e.Browser.URL;
                }));
            }
            else
            {
                this.Title = e.Browser.URL;
            }
        }
    };
browserView.Browser.LoadURL("teamdev.com");

VB.NET

Dim browserView As BrowserView = New WPFBrowserView(BrowserFactory.Create())
AddHandler browserView.Browser.FinishLoadingFrameEvent,
    sub(ByVal sender As Object, ByVal e As FinishLoadingEventArgs)

        If e.IsMainFrame Then

            If Not Dispatcher.CheckAccess() Then
                Dispatcher.Invoke(Sub()
                                      Me.Title = e.Browser.URL
                                  End Sub)
            Else
                Me.Title = e.Browser.URL
            End If
        End If
    End sub

browserView.Browser.LoadURL("teamdev.com")