项目中碰到此需求。几番比对,此为最好的解决方案,聊做备忘。
1、加入Microsoft Internet Controls引用:
项目右键->添加引用->COM->Microsoft Internet Controls,加入后,其引用名为SHDocVw。
2、扩展WebBrowser控件:
public class WebBrowser : System.Windows.Forms.WebBrowser { public delegate void NewWindow3EventHandler(ref bool Cancel, string bstrUrl); //发布NewWindow3事件 public event NewWindow3EventHandler NewWindow3; protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); if (this.ActiveXInstance != null) { var browser = this.ActiveXInstance as SHDocVw.WebBrowser; browser.NewWindow3 += WebBrowser_NewWindow3; } } private void WebBrowser_NewWindow3(ref object ppDisp, ref bool Cancel, uint dwFlags, string bstrUrlContext, string bstrUrl) { var handler = NewWindow3; if (handler != null) handler(ref Cancel, bstrUrl); } }
3、使用:
代替原生WebBrowser,处理NewWindow3事件:
private void browser_NewWindow3(ref bool Cancel, string bstrUrl) { Cancel = true; browser.Navigate(bstrUrl); }
完美实现!
其它方案,都不好用,比如:
private void browser_NewWindow(object sender, CancelEventArgs e) { //打开新窗口的方式是在已有的窗口内打开...可能为空 webBrowser.Url = new Uri(((WebBrowser)sender).StatusText); e.Cancel = true; }
private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { //将所有的链接的目标,指向本窗体...实测,没啥用 foreach (HtmlElement archor in this.webBrowser.Document.Links) { archor.SetAttribute("target", "_self"); } //将所有的FORM的提交目标,指向本窗体 foreach (HtmlElement form in this.webBrowser.Document.Forms) { form.SetAttribute("target", "_self"); } }
private void wB_MainBrowser_NewWindow(object sender, CancelEventArgs e) { e.Cancel = true; try {
//有javascript: {0}这样的东西 string url = this.wB_MainBrowser.Document.ActiveElement.GetAttribute("href"); this.wB_MainBrowser.Url = new Uri(url); } catch { } }
参考资料:
c# - NewWindow3 Event Not Fired - Stack Overflow
.net - Open link in same window with WebBrowser control - Stack Overflow