在新的选项卡中打开链接(WebBrowser控件)

12

请问有谁知道如何在WinForms应用程序的WebBrowser控件中单击链接,然后使该链接在我的TabControl内以新标签页的形式打开吗?

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

非常感谢任何建议/示例。

谢谢。


我也遇到了一个问题,每当我在自己的浏览器中点击网页链接时,IE就会打开。尝试了以上所有方法,但没有成功。Robert的第一条回复中提到了添加ExtendedWebBrowser,但是在代码的最后一行仍然出现了红线并警告“InitialTabBroswer在当前上下文中不存在”。如果有更多的提示或建议将不胜感激。 - user1169764
6个回答

26

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

为了可靠地实现此目标,您需要获取NewWindow2事件,该事件公开了ppDisp(应打开新窗口的WebBrowser控件的可设置指针)。 所有其他可能的拼凑解决方案(例如,在OpenWindow事件之前获取用户选择的最后一个链接)都不是最佳的,而且在某些情况下可能会失败。

幸运的是,有一种(相对)简单的方法可以在仍使用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

一旦您有了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);

    }

假设存在一个名为“Tabs”的TabControl控件,其中包含名为“InitialWebBrowser”的ExtendedWebBrowser控件。

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


非常感谢Robert提供的示例代码和链接 :-) 我有几个问题,我添加了一个类并将其命名为ExtendedWebBrowser.cs,然后将您的示例代码添加到Form1.cs文件中,但在尝试调试时出现以下错误:"参数'1'无法从'System.Windows.Forms.WebBrowser'转换为'ExtendedWebBrowser'。" 并且蓝色波浪线出现在以下代码行下面:InitializeBrowserEvents(InitialTabBrowser); 您知道这是什么吗? - jay_t55
1
请确保您的InitialWebBrowser类型为“ExtendedWebBrowser”,看起来您仍在使用“WebBrowser”。要添加ExtendedWebBrowser,请查看工具箱。您应该在顶部看到它,并在旁边带有一个小齿轮符号。这是您应该在设计模式下添加到InitialWebBrowser控件的内容。 - Robert Venables
由于某些奇怪的原因,即使我使用ExtendedWebBrowser并使用NewWindow2事件创建新的Web浏览器,新窗口仍在外部Web浏览器中打开。 - Kosmo零

4
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;
}

谢谢sshow,那非常有帮助,不过我正在尝试获取发送到新浏览器窗口的URL,以便我可以阻止新浏览器打开并在我的浏览器中打开该URL的新选项卡?例如,当我右键单击链接并选择在新窗口中打开时,我不想它在新IE中打开,而是想在我的Web浏览器中打开一个新选项卡。 - jay_t55
1
也许你可以重写“在新窗口中打开”按钮的上下文菜单。我从未尝试过这样的事情。祝好运! - sshow

3

我做了一些有关这个主题的研究,发现不需要在 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);
    }

请阅读http://bit.ly/IDWm5A获取更多信息。这是系列中的第5页,为了完全理解,我不得不回去阅读第3-5页。

这是什么?如何使用它? - Kosmo零

3
以下代码可以正常运行,只需按照第一个回复创建ExtendedWebBrowser类即可。
我使用这个方法来打开新标签页,但它也适用于在您的浏览器中打开新窗口而不是IE。
希望对您有所帮助。
 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); 
        }

0

您可以取消新窗口事件并自己处理导航和选项卡相关的内容。

这里有一个完整的工作示例。假设您已经有了一个选项卡控件和至少一个选项卡页面。

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;
        }
    }
}

-3

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接