The onbeforeunload event fires when the document is about to be unloaded. This event allows you to display a message in a confirmation dialog box to inform the user whether he/she wants to stay or leave the current page. DotNetBrowser API allows handling this dialog using DialogHandler API. By default, the dialog is displayed. Using your custom implementation of theDialogHandler, you can handle this dialog in your own way. For example, you can display your custom message dialog or suppress the dialog and don't allow unloading web page.


The following sample demonstrates how to handle the onbeforeunload dialog:


MainWindow.xaml

<Window x:Class="WPFDialogHandlerSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpf="clr-namespace:DotNetBrowser.WPF;assembly=DotNetBrowser"
        Title="MainWindow" Height="350" Width="525">
    <Grid Name="mainLayout">
        <wpf:WPFBrowserView Name="browserView"/>
    </Grid>
</Window>

C#

MainWindow.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using DotNetBrowser;
using DotNetBrowser.WPF;

namespace WPFDialogHandlerSample
{

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            // Initialize WPF Application UI.
            InitializeComponent();

            var defaultHandler = browserView.Browser.DialogHandler;
            browserView.Browser.DialogHandler = new CustomDialogHandler(defaultHandler);

            // Load HTML from string into BrowserView.
            browserView.Browser.LoadHTML("<html><body onbeforeunload='return myFunction()'>" +
                "<a href='http://www.google.com'>Click here to leave</a>" +
                "<script>function myFunction() { return 'Leave this web page?'; }" +
                "</script></body></html>");
        }
    }

    public class CustomDialogHandler : DialogHandler
    {
        private DialogHandler defaultHandler;

        public CustomDialogHandler(DialogHandler defaultHandler)
        {
            this.defaultHandler = defaultHandler;
        }

        public CloseStatus OnBeforeUnload(UnloadDialogParams parameters) {
            CloseStatus returnValue = CloseStatus.CANCEL;
            String title = "Confirm Navigation";
            String message = parameters.Message;
            MessageBoxResult result = MessageBox.Show(message, title, MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (result == MessageBoxResult.Yes)
            {
                returnValue = CloseStatus.OK;
            }
            return returnValue;
        }

        public void OnAlert(DialogParams parameters)
        {
            defaultHandler.OnAlert(parameters);
        }

        public CloseStatus OnConfirmation(DialogParams parameters)
        {
            return defaultHandler.OnConfirmation(parameters);
        }

        public CloseStatus OnFileChooser(FileChooserParams parameters)
        {
            return defaultHandler.OnFileChooser(parameters);
        }

        public CloseStatus OnPrompt(PromptDialogParams parameters)
        {
            return defaultHandler.OnPrompt(parameters);
        }

        public CloseStatus OnReloadPostData(ReloadPostDataParams parameters)
        {
            return defaultHandler.OnReloadPostData(parameters);
        }

        public CloseStatus OnColorChooser(ColorChooserParams parameters)
        {
            return defaultHandler.OnColorChooser(parameters);
        }

        public CloseStatus OnSelectCertificate(CertificatesDialogParams parameters)
        {
            return defaultHandler.OnSelectCertificate(parameters);
        }
    }
}

VB.NET

MainWindow.xaml.vb

Imports DotNetBrowser

Namespace WPFDialogHandlerSample
    Class MainWindow
        Inherits Window

        Sub New()
            ' Initialize WPF Application UI.
            InitializeComponent()

            Dim defaultHandler = browserView.Browser.DialogHandler
            browserView.Browser.DialogHandler = new CustomDialogHandler(defaultHandler)

            ' Load HTML from string into BrowserView.
            browserView.Browser.LoadHTML("<html><body onbeforeunload='return myFunction()'>" +
                                         "<a href='http://www.google.com'>Click here to leave</a>" +
                                         "<script>function myFunction() { return 'Leave this web page?'; }" +
                                         "</script></body></html>")
        End Sub
    End Class

    Friend Class CustomDialogHandler
        Implements DialogHandler

        Private defaultHandler As DialogHandler

        Public Sub New(defaultHandler As DialogHandler)
            Me.defaultHandler = defaultHandler
        End Sub

        Public Function OnBeforeUnload(parameters As UnloadDialogParams) As CloseStatus _
            Implements DialogHandler.OnBeforeUnload
            Dim returnValue As CloseStatus = CloseStatus.CANCEL
            Dim title As String = "Confirm Navigation"
            Dim message As String = parameters.Message
            Dim result As MessageBoxResult = MessageBox.Show(message, title, MessageBoxButton.YesNo,
                                                             MessageBoxImage.Question)
            If result = MessageBoxResult.Yes Then

                returnValue = CloseStatus.OK
            End If
            return returnValue
        End Function

        Public Sub OnAlert(parameters As DialogParams) Implements DialogHandler.OnAlert
            defaultHandler.OnAlert(parameters)
        End Sub

        Public Function OnColorChooser(parameters As ColorChooserParams) As CloseStatus _
            Implements DialogHandler.OnColorChooser
            return defaultHandler.OnColorChooser(parameters)
        End Function

        Public Function OnConfirmation(parameters As DialogParams) As CloseStatus _
            Implements DialogHandler.OnConfirmation
            return defaultHandler.OnConfirmation(parameters)
        End Function

        Public Function OnFileChooser(parameters As FileChooserParams) As CloseStatus _
            Implements DialogHandler.OnFileChooser
            return defaultHandler.OnFileChooser(parameters)
        End Function

        Public Function OnPrompt(parameters As PromptDialogParams) As CloseStatus Implements DialogHandler.OnPrompt
            return defaultHandler.OnPrompt(parameters)
        End Function

        Public Function OnReloadPostData(parameters As ReloadPostDataParams) As CloseStatus _
            Implements DialogHandler.OnReloadPostData
            return defaultHandler.OnReloadPostData(parameters)
        End Function

        Public Function OnSelectCertificate(parameters As CertificatesDialogParams) As CloseStatus _
            Implements DialogHandler.OnSelectCertificate
            return defaultHandler.OnSelectCertificate(parameters)
        End Function
    End Class
End Namespace


Starting from DotNetBrowser 1.19 it is possible to prevent disposing of the Browser instance if the web page has the onbeforeunload event. For this purpose, it is necesary to execute Browser.Dispose(bool checkBeforeUnload) method with the flag  true.


Note: this method should be executed in the non-UI thread. Otherwise, occurs the deadlock.


This code sample demonstrates how to use it with the FormClosing event:

 C#

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    try
    {
        Task<bool> disposeTask = browserView.Browser.Dispose(true);

        if (disposeTask.IsCompleted)
        {
            e.Cancel = !disposeTask.Result;
            return;
        }

        e.Cancel = true;

        disposeTask.ContinueWith(t =>
        {
            if (t.Result)
            {
                BeginInvoke((Action) (() =>
                {
                    FormClosing -= Form1_FormClosing;
                    Close();
                }));
            }
        });
    }
    catch (Exception exception)
    {
        Console.WriteLine(exception);
    }
}

VB.NET

Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs)
    Try
        Dim disposeTask As Task(Of Boolean) = browserView.Browser.Dispose(True)

        If disposeTask.IsCompleted Then
            e.Cancel = Not disposeTask.Result
            Return
        End If

        e.Cancel = True
        disposeTask.ContinueWith(Sub(t)

            If t.Result Then
                BeginInvoke(CType((Sub()
                    RemoveHandler FormClosing, AddressOf Form1_FormClosing
                    Close()
                End Sub), Action))
            End If
        End Sub)
    Catch exception As Exception
        Console.WriteLine(exception)
    End Try
End Sub