winforms 在WebView2中触发onbeforeunload

e7arh2l6  于 2023-06-06  发布在  其他
关注(0)|答案(2)|浏览(182)

answer演示如何通过以下方式在WebBrowser控件中触发onbeforeunload事件:

protected override void OnFormClosing(FormClosingEventArgs e)
{
    if (!this.formsWebBrowser.IsDisposed)
    {
        //// Generate SHDocVw.dll: Visual Studio Developer Command Prompt "tlbimp.exe ieframe.dll /out: C:\temp\SHDocVw.dll",
        var activeX = this.formsWebBrowser.ActiveXInstance;
        var input = Type.Missing;
        object leavePage = true;
        ((SHDocVw.WebBrowser)activeX).ExecWB(
            SHDocVw.OLECMDID.OLECMDID_ONUNLOAD,
            SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT,
            ref input,
            ref leavePage);
        if (!(bool)leavePage)
        {
            e.Cancel = true;
            return;
        }
    }

    base.OnFormClosing(e);
}

但是现在试图从IE11(如WebBrowser所使用的)转移到带有WebView 2控件的Edge Chromium,我不知道如何在WebView 2中做同样的事情。
将WebView 2导航到另一个页面时,对话框正确显示。当用户关闭应用程序或包含WebView 2的窗口时,问题就会出现。然后它只是关闭,不显示任何对话框。
这就是上面的代码对WebBrowser控件所做的,当关闭应用程序时,IE11浏览器中的(on)beforeonload事件被触发,并返回一个bool。如果用户按下“离开”或没有beforeonload事件活动,则为True;如果用户按下“停留在页面上”,则为false。
调用 ExecuteScriptAsync(“onbeforeunload();“)(在使用 window设置事件时不起作用。addEventListener(“beforeunload”,function(event){...});)如何在WebView 2中完成相同的操作?

编辑:

问题是我不想总是在关闭时显示对话框,除非我真的必须这样做。我只想在页面有未保存的更改时显示它(它在JavaScript中的beforeunload事件中进行通信)。我知道在C#代码中处理这个问题的唯一方法是触发内置的onunload事件,在浏览器中显示beforeunload对话框。这正是ActiveXInstance.ExecWB(OLECMDID_ONUNLOAD)为WebBrowser控件和IE11所做的。
在WebView 2/Chromium中可能无法以相同的方式触发该事件?我就是这个意思。我尝试在FormClosing事件中调用JavaScript,但应用程序只是关闭,而没有等待响应。
我想唯一的其他选择是删除x-close按钮,并使用一个自定义的关闭按钮,可以做所需的检查,然后关闭应用程序。

dl5txlt9

dl5txlt91#

这对我很有效。你可以把它和一个窗体关闭或其他东西结合起来。不要忘记在适当的地方正确地分离事件/处置。这只是一个样本。

public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            DoWork();
        }

        private async Task DoWork()
        {
            await webView21.EnsureCoreWebView2Async();
            webView21.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false;
            webView21.CoreWebView2.ScriptDialogOpening += CoreWebView2_ScriptDialogOpening;
            await webView21.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.addEventListener('beforeunload', function(e) { return event.returnValue = 'prompt';});");

            webView21.Source = new Uri("https://www.google.com");
        }

        private void CoreWebView2_ScriptDialogOpening(object sender, Microsoft.Web.WebView2.Core.CoreWebView2ScriptDialogOpeningEventArgs e)
        {
            if (MessageBox.Show("do you want to leave", "Leave?", MessageBoxButtons.OKCancel) == DialogResult.OK)
            {
                e.Accept();
            }
            else
            {
                e.GetDeferral();
            }
        }
wsxa1bj1

wsxa1bj12#

因为我想做同样的事情,这是不可能的,因为根据WebView2Feedback github中的评论:
在WebView2示例上调用Close()时,无论AreDefaultScriptDialogsEnabled的标志值如何,都不会显示beforeunload对话框。此决定是因为应用程序在浏览器处理事件之前启动了关闭过程,即使用户单击取消,我们也无法获取任何会话信息。

相关问题