WinFormsアプリケーションのWebBrowserコントロールのリンクをクリックして、そのリンクをTabControl内の新しいタブで開く方法を知っている人はいますか?
私は何ヶ月も検索していて、多くのチュートリアル/記事/コードサンプルを見てきましたが、これまでC#でこれを試した人はいないようです。
アドバイス/サンプルは大歓迎です。
ありがとうございました。
あなたのコメントに基づいて、WebBrowserコントロールの「新しいウィンドウで開く」アクションをトラップし、代わりにアプリケーション内の新しいタブで開くようにデフォルトの動作をオーバーライドしたいと思います。
これを確実に実行するには、ppDisp(新しいウィンドウを開く必要があるWebBrowserコントロールへの設定可能なポインター)を公開するNewWindow2イベントを取得する必要があります。他の潜在的なハッキングされたソリューション(OpenWindowイベントの前にユーザーが選択した最後のリンクを取得するなど)はすべて最適ではなく、コーナーケースでは失敗することになります。
幸いなことに、System.Windows.Forms.WebBrowserコントロールをベースとして使用しながら、これを実現する(比較的)簡単な方法があります。あなたがする必要があるのは、ActiveXインスタンスへのパブリックアクセスを提供しながら(新しいタブでppDispに渡すために)WebBrowserを拡張してNewWindow2イベントをインターセプトすることです。これは以前に行われたことがあり、Mauricio Rojasには、完全な労働者階級「ExtendedWebBrowser」を備えた優れた例があります。
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を含む初期タブを想定しています)
タブを閉じたら、イベントの登録を解除することを忘れないでください!
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;
}
私はこのトピックについて少し調査しましたが、そのコードは生成されたInterop.SHDocVwにすでに存在するため、ExtendedWebBrowserクラスに存在するすべてのCOM配管を実行する必要はありません。そのため、以下のより自然な構成を使用して、NewWindow2イベントをサブスクライブすることができました。 Visual Studioで、「MicrosoftInternetControls」への参照を追加する必要がありました。
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ページ目に戻って読む必要がありました。
次のコードは機能します。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);
}
新しいウィンドウイベントをキャンセルして、ナビゲーションとタブを自分で処理するだけです。
これが完全に機能する例です。これは、タブコントロールと少なくとも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;
}
}
}