1

当单击 webview2 - C# windows 窗体中的 Edge 中的链接时,请提供代码片段以创建选项卡而不是在新窗口中打开页面。

遵循以下步骤。

  1. 在 C# windows 窗体上拖动 webview2 控件并更新源属性链接:https ://example.com

  2. https://example.com站点在webview2中打开成功

  3. 单击站点中的几个链接 - https://example.com并打开新窗口并寻找在新选项卡中打开这个而不是在新窗口中打开它

  4. 调试代码时,此事件 webView.CoreWebView2.NewWindowRequested 从未命中。如果引发此 webView.CoreWebView2.NewWindowRequested 事件,则 webview 类上没有导航方法可用,并且它在 corewebview2 类上可用,如果我们使用它,则会获得空引用异常。

4

2 回答 2

3

为了完整起见,由于 David Risney 的解释,我能够实现同样的目标。不幸的是,它没有包含任何代码,但我使用1.0.721-prereleaseand实现了这一点Microsoft.WebView2.FixedVersionRuntime.87.0.664.66.x64

程序.cs:

using System;
using System.Windows.Forms;

namespace TestApp1
{
    static class Program
    {
        public static Microsoft.Web.WebView2.Core.CoreWebView2Environment WebView2Environment;

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Form1.cs:

using System;
using System.Windows.Forms;

namespace TestApp1
{
    public partial class Form1 : Form
    {
        public Microsoft.Web.WebView2.Core.CoreWebView2Deferral Deferral;
        public Microsoft.Web.WebView2.Core.CoreWebView2NewWindowRequestedEventArgs Args;

        public Form1()
        {
            InitializeComponent();
            webView21.CoreWebView2InitializationCompleted += webView21_CoreWebView2InitializationCompleted_1;
        }

        private void CoreWebView2_NewWindowRequested(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NewWindowRequestedEventArgs e)
        {
            Form1 f = new Form1();
            f.Args = e;
            f.Deferral = e.GetDeferral();
            f.Show();
        }

        private async void Form1_Load(object sender, EventArgs e)
        {
            if (Program.WebView2Environment == null)
                Program.WebView2Environment = Microsoft.Web.WebView2.Core.CoreWebView2Environment.CreateAsync(@"C:\Users\Dragon\Downloads\Microsoft.WebView2.FixedVersionRuntime.87.0.664.66.x64", $@"C:\Users\Dragon\Desktop\Test{Guid.NewGuid()}").Result;
            await webView21.EnsureCoreWebView2Async(Program.WebView2Environment);
            webView21.Source = new Uri("http://www.google.com");
        }

        private void webView21_CoreWebView2InitializationCompleted_1(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
        {
            if (!e.IsSuccess) { MessageBox.Show($"{e.InitializationException}"); }

            if (Deferral != null)
            {
                Args.NewWindow = webView21.CoreWebView2;
                Deferral.Complete();
            }

            webView21.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            webView21.ExecuteScriptAsync($@"window.open('http://www.bing.com', '_blank');");
        }
    }
}

所以它的工作方式有点奇怪:要生成一个新窗口,你可以通过 JavaScript 使用ExecuteScriptAsync. 在这种情况下,我将打开一个新窗口到 bing.com。因此,这会调用CoreWebView2_NewWindowRequested. 为了让事件通过并且代码可以工作(否则它会冻结),它必须经历这一切。因此,您不能设置当前正在发生的事件NewWindow的内部属性。CoreWebView2NewWindowRequestedEventArgs

解决方案是将事件数据(args 和 deferral)带到新表单中,显示它,并在加载时和控件CoreWebView2属性不为 null / 已初始化后,通过调用CoreWebView2InitializationCompleted检查 args/deferral 是否不为 null 和然后将 defer 称为Complete()(这基本上就像一个 JS 承诺)并且在这里您可以将NewWindow属性设置为CoreWebView2已初始化,因此它不为空。

希望这将回答您的问题和未来的读者。使用此代码,我能够使其工作。

于 2021-01-01T22:41:58.630 回答
2

WebView2 中没有对选项卡的内置支持。但是,您可以使用 NewWindowRequested 事件拦截新窗口,并提供您自己的 CoreWebView2 作为该新窗口,并将该 CoreWebView2 按您喜欢的方式放置在您的 UI 中。例如,可以将新的 CoreWebView2 放置在您的 UI 中,使其看起来像一个新选项卡。(听起来这就是你正在做的事情,但在这里明确声明只是为了确保我正确理解你的场景。)

关于为空的 WebView2.CoreWebView2 属性,您可以调用EnsureCoreWebView2Async并等待返回的任务,也可以设置 WebView2.Source 属性并等待派发 CoreWebView2Ready 事件,以便填写 WebView2.CoreWebView2 属性。之前为空那。

另外,如果您需要获取CoreWebView2来填写NewWindowRequestedEventArg的NewWindow属性,由于上述从WebView2实例获取CoreWebView2的步骤都是异步的,您需要在NewWindowRequested开始异步工作之前调用NewWindowRequestedEventArg的GetDeferral方法事件处理程序并在 NewWindowRequested 事件处理程序中完成异步工作后在 Deferral 上调用 Complete。

如果您发现 WebView2 正在打开新窗口但 NewWindowRequested 事件未触发的情况,请在https://github.com/MicrosoftEdge/WebViewFeedback打开错误。您在 WebView2 中使用什么版本的 SDK 和浏览器?现在修复了一些错误,在某些情况下打开新窗口不会触发 NewWindowRequested 事件。

于 2020-07-08T22:08:33.703 回答