使用 WebView2 - Edge 创建选项卡 [英] Create tabs using WebView2 - Edge
问题描述
当点击 webview2 - Edge in C# windows form 中的链接时,请提供用于创建选项卡而不是在新窗口中打开页面的代码片段.
Please provide the code snippet to create a tab instead of open a page in new window when click on the links in the webview2 - Edge in C# windows form.
按照以下步骤操作.
在 C# windows 窗体上拖动 webview2 控件并更新源属性链接:https://example.com一个>
https://example.com 网站在 webview2 中成功打开
https://example.com site opened successfully in the webview2
点击站点中的几个链接 - https://example.com 并打开新的窗口并寻找在新选项卡中打开这个而不是在新窗口中打开它
click on few links in the site - https://example.com and it opens the new window and looking for open this one in the new tab instead of open it in new window
在调试代码时,这个事件 webView.CoreWebView2.NewWindowRequested 从不命中.如果引发此 webView.CoreWebView2.NewWindowRequested 事件,则 webview 类上没有可用的导航方法,并且它在 corewebview2 类上可用,如果我们使用它,则会获得空引用异常.
This event webView.CoreWebView2.NewWindowRequested never hit when debug the code. In case if this webView.CoreWebView2.NewWindowRequested event raised then no navigate method is available on webview class and its available on corewebview2 classs and getting the null reference exception if we use this.
推荐答案
为了完整起见,感谢 David Risney 的解释,我能够实现同样的目标.不幸的是它没有包含任何代码,但我使用 1.0.721-prerelease
和 Microsoft.WebView2.FixedVersionRuntime.87.0.664.66.x64
实现了这一点:
For the sake of completeness, I was able to achieve the same thing thanks to David Risney's explanation. Unfortunately it didn't include any code, but I achieved this using 1.0.721-prerelease
and Microsoft.WebView2.FixedVersionRuntime.87.0.664.66.x64
:
Program.cs:
Program.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');");
}
}
}
所以这种工作方式有点奇怪:要生成一个新窗口,您可以使用 ExecuteScriptAsync
通过 JavaScript 来完成.在这种情况下,我将打开一个访问 bing.com 的新窗口.因此,这会调用 CoreWebView2_NewWindowRequested
.要使事件通过并使代码工作(否则它会冻结),它必须全部通过.因此,您不能在当前发生的事件中设置 CoreWebView2NewWindowRequestedEventArgs
的 NewWindow
属性.
So the way this works is kinda weird: To spawn a new window, you can do it through JavaScript using ExecuteScriptAsync
. In this case I'm opening a new window to bing.com. So, that makes a call to CoreWebView2_NewWindowRequested
. For the event to pass and the code to work (otherwise it will freeze) it must go through it all. So, you cannot set the NewWindow
property of the CoreWebView2NewWindowRequestedEventArgs
inside the event that's currently happening.
解决方案是将事件数据(args & deferral)带到新表单中,显示它,并在加载时和之后控件的 CoreWebView2
属性不为空/已初始化,通过调用CoreWebView2InitializationCompleted
,检查args/deferral是否不为空,然后将defer调用为Complete()
(这基本上就像一个JS承诺) AND 在这里您可以设置 NewWindow
属性,因为 CoreWebView2
已被初始化,因此它不为空.
The solution is to take the event data (args & deferral) to the new form, show it, and upon load and after the CoreWebView2
property of the control is not null / has initialized, by calling CoreWebView2InitializationCompleted
, check if args/deferral are not null and then call the defer as Complete()
(this is basically like a JS promise) AND here you can set the NewWindow
property as CoreWebView2
has been initialized and therefore it's not null.
希望这能回答您和未来的读者的问题.有了这段代码,我就可以让它工作了.
Hopefully this will answer your question and future readers. With this code, I was able to make it work.
这篇关于使用 WebView2 - Edge 创建选项卡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!