C# 在新选项卡(WebBrowser Control)中打开链接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1286746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:41:00  来源:igfitidea点击:

Open link in new TAB (WebBrowser Control)

c#.netwinformswebbrowser-controltabcontrol

提问by jay_t55

Does anybody know how to click on a link in the WebBrowser control in a WinForms application and then have that link open in a new tab inside my TabControl?

有人知道如何在 WinForms 应用程序中单击 WebBrowser 控件中的链接,然后在我的 TabControl 内的新选项卡中打开该链接吗?

I've been searching for months, seen many tutorials/articles/code samples but it seems as though nobody has ever tried this in C# before.

我已经搜索了几个月,看过很多教程/文章/代码示例,但似乎以前没有人在 C# 中尝试过。

Any advice/samples are greatly appreciated.

非常感谢任何建议/样品。

Thank you.

谢谢你。

采纳答案by Robert Venables

Based on your comments, I understand that you want to trap the "Open In New Window" action for the WebBrowser control, and override the default behavior to open in a new tab inside your application instead.

根据您的评论,我了解到您想要捕获 WebBrowser 控件的“在新窗口中打开”操作,并覆盖默认行为以在应用程序内的新选项卡中打开。

To accomplish this reliably, you need to get at the NewWindow2 event, which exposes ppDisp (a settable pointer to the WebBrowser control that should open the new window). All of the other potential hacked together solutions (such as obtaining the last link selected by the user before the OpenWindow event) are not optimal and are bound to fail in corner cases.

要可靠地完成此操作,您需要获取 NewWindow2 事件,该事件公开 ppDisp(指向应打开新窗口的 WebBrowser 控件的可设置指针)。所有其他潜在的黑客解决方案(例如获取用户在 OpenWindow 事件之前选择的最后一个链接)都不是最佳的,并且在极端情况下必然会失败。

Luckily, there is a (relatively) simple way of accomplishing this while still using the System.Windows.Forms.WebBrowser control as a base. All you need to do is extend the WebBrowser and intercept the NewWindow2 event while providing public access to the ActiveX Instance (for passing into ppDisp in new tabs). This has been done before, and Mauricio Rojas has an excellent example with a complete working class "ExtendedWebBrowser":

幸运的是,有一种(相对)简单的方法可以在仍然使用 System.Windows.Forms.WebBrowser 控件作为基础的情况下完成此操作。您需要做的就是扩展 WebBrowser 并拦截 NewWindow2 事件,同时提供对 ActiveX 实例的公共访问(用于在新选项卡中传递到 ppDisp)。之前已经这样做过,Mauricio Rojas 有一个很好的例子,里面有一个完整的工作类“ExtendedWebBrowser”:

http://blogs.artinsoft.net/mrojas/archive/2008/09/18/newwindow2-events-in-the-c-webbrowsercontrol.aspx

http://blogs.artinsoft.net/mrojas/archive/2008/09/18/newwindow2-events-in-the-c-webbrowsercontrol.aspx

Once you have the ExtendedWebBrowser class, all you need to do is setup handlers for NewWindow2 and point ppDisp to a browser in a new tab. Here's an example that I put together:

一旦你有了 ExtendedWebBrowser 类,你需要做的就是为 NewWindow2 设置处理程序并将 ppDisp 指向新选项卡中的浏览器。这是我放在一起的一个例子:

    private void InitializeBrowserEvents(ExtendedWebBrowser SourceBrowser)
    {
        SourceBrowser.NewWindow2 += new EventHandler<NewWindow2EventArgs>(SourceBrowser_NewWindow2);
    }

    void SourceBrowser_NewWindow2(object sender, NewWindow2EventArgs e)
    {

        TabPage NewTabPage = new TabPage()
        {
            Text = "Loading..."
        };

        ExtendedWebBrowser NewTabBrowser = new ExtendedWebBrowser()
        {
            Parent = NewTabPage,
            Dock = DockStyle.Fill,
            Tag = NewTabPage
        };

        e.PPDisp = NewTabBrowser.Application;
        InitializeBrowserEvents(NewTabBrowser);

        Tabs.TabPages.Add(NewTabPage);
        Tabs.SelectedTab = NewTabPage;

    }

    private void Form1_Load(object sender, EventArgs e)
    {

        InitializeBrowserEvents(InitialTabBrowser);

    }

(Assumes TabControl named "Tabs" and initial tab containing child control docked ExtendedWebBrowser named "InitialWebBrowser")

(假设名为“Tabs”的 TabControl 和包含子控件停靠的 ExtendedWebBrowser 名为“InitialWebBrowser”的初始选项卡)

Don't forget to unregister the events when the tabs are closed!

不要忘记在选项卡关闭时取消注册事件!

回答by sshow

private Uri _MyUrl;    

System.Windows.Forms.WebBrowser browser = new System.Windows.Forms.WebBrowser();
browser.Navigating += new System.Windows.Forms.WebBrowserNavigatingEventHandler(browser_Navigating);


void browser_Navigating(object sender, System.Windows.Forms.WebBrowserNavigatingEventArgs e)
{
    _MyUrl = e.Url;
    e.Cancel;
}

回答by svinto

There is no tabbing in the web browser control, therefor you need to handle the tabs yourself. Add a tab control above the web browser control and create new web browser controls when new tabs are being opened. Catch and cancel when the user opens new windows and open new tabs instead.

Web 浏览器控件中没有选项卡,因此您需要自己处理选项卡。在 Web 浏览器控件上方添加一个选项卡控件,并在打开新选项卡时创建新的 Web 浏览器控件。当用户打开新窗口并打开新选项卡时捕获并取消。

回答by Dev

The following code works, just follow the first reply for creating the ExtendedWebBrowser class.

以下代码有效,只需按照创建 ExtendedWebBrowser 类的第一个回复即可。

I'm using this to open a new tab but it also works to open a new window using your browser and not IE.

我正在使用它来打开一个新选项卡,但它也可以使用浏览器而不是 IE 打开一个新窗口。

Hope it helps.

希望能帮助到你。

 private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        if (current_tab_count == 10) return;
        TabPage tabPage = new TabPage("Loading...");
        tabpages.Add(tabPage);
        tabControl1.TabPages.Add(tabPage);
        current_tab_count++;
        ExtendedWebBrowser browser = new ExtendedWebBrowser();
        InitializeBrowserEvents(browser);
        webpages.Add(browser);
        browser.Parent = tabPage;
        browser.Dock = DockStyle.Fill;
        browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(browser_DocumentCompleted);
        browser.DocumentTitleChanged += new EventHandler(Browser_DocumentTitleChanged);
        browser.Navigated += Browser_Navigated;
        browser.IsWebBrowserContextMenuEnabled = true;
public void InitializeBrowserEvents(ExtendedWebBrowser browser)
    {
        browser.NewWindow2 += new EventHandler<ExtendedWebBrowser.NewWindow2EventArgs>(Browser_NewWindow2);
    }

    void Browser_NewWindow2(object sender, ExtendedWebBrowser.NewWindow2EventArgs e)
    {

        if (current_tab_count == 10) return;
        TabPage tabPage = new TabPage("Loading...");
        tabpages.Add(tabPage);
        tabControl1.TabPages.Add(tabPage);
        current_tab_count++;
        ExtendedWebBrowser browser = new ExtendedWebBrowser();
        webpages.Add(browser);
        browser.Parent = tabPage;
        browser.Dock = DockStyle.Fill;
        browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(browser_DocumentCompleted);
        browser.DocumentTitleChanged += new EventHandler(Browser_DocumentTitleChanged);
        browser.Navigated += Browser_Navigated;
        tabControl1.SelectedTab = tabPage;
        browser.Navigate(textBox.Text);

        {
            e.PPDisp = browser.Application;
            InitializeBrowserEvents(browser); 
        }

回答by eugen_nw

I did a bit of research on this topic and one does not need to do all the COM plumbing that is present in the ExtendedWebBrowser class, as that code is already present in the generated Interop.SHDocVw. As such, I was able to use the more natural construct below to subscribe to the NewWindow2 event. In Visual Studio I had to add a reference to "Microsoft Internet Controls".

我对这个主题做了一些研究,不需要执行 ExtendedWebBrowser 类中存在的所有 COM 管道,因为该代码已经存在于生成的 Interop.SHDocVw 中。因此,我能够使用下面更自然的构造来订阅 NewWindow2 事件。在 Visual Studio 中,我必须添加对“Microsoft Internet Controls”的引用。

    using SHDocVw;
    ...

    internal WebBrowserSsoHost(System.Windows.Forms.WebBrowser webBrowser,...)
    {
        ParameterHelper.ThrowOnNull(webBrowser, "webBrowser");
        ...

        (webBrowser.ActiveXInstance as WebBrowser).NewWindow2 += OnNewWindow2;
    }

    private void OnNewWindow2(ref object ppDisp, ref bool Cancel)
    {
        MyTabPage tabPage = TabPageFactory.CreateNewTabPage();
        tabPage.SetBrowserAsContent(out ppDisp);
    }

Please read http://bit.ly/IDWm5Afor more info. This is page #5 in the series, for a complete understanding I had to go back and read pages 3 -> 5.

请阅读http://bit.ly/IDWm5A了解更多信息。这是该系列的第 5 页,为了完全理解,我必须返回并阅读第 3 -> 5 页。

回答by Alexander Ryan Baggett

You simply cancel the new window event and handle the navigation and tab stuff yourself.

您只需取消新窗口事件并自己处理导航和选项卡内容。

Here is a fully working example. This assumes you have a tabcontrol and at least 1 tab page in place.

这是一个完全有效的示例。这假设您有一个 tabcontrol 和至少 1 个标签页。

using System.ComponentModel;
using System.Windows.Forms;

namespace stackoverflow2
{

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.webBrowser1.NewWindow += WebBrowser1_NewWindow;
            this.webBrowser1.Navigated += Wb_Navigated;
            this.webBrowser1.DocumentText=
             "<html>"+
             "<head><title>Title</title></head>"+
             "<body>"+
             "<a href = 'http://www.google.com' target = 'abc' > test </a>"+
             "</body>"+
             "</html>";
        }
        private void WebBrowser1_NewWindow(object sender, CancelEventArgs e)
        {
            e.Cancel = true; //stop normal new window activity

            //get the url you were trying to navigate to
            var url= webBrowser1.Document.ActiveElement.GetAttribute("href");

            //set up the tabs
            TabPage tp = new TabPage();
            var wb = new WebBrowser();
            wb.Navigated += Wb_Navigated;
            wb.Size = this.webBrowser1.Size;
            tp.Controls.Add(wb);
            wb.Navigate(url);
            this.tabControl1.Controls.Add(tp);
            tabControl1.SelectedTab = tp;
        }

        private void Wb_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            tabControl1.SelectedTab.Text = (sender as WebBrowser).DocumentTitle;
        }
    }
}