WPF中自带一个WebBrowser控件,当我们使用它打开一个网页,例如百度,然后点击它其中的链接时,如果这个链接是会弹出一个新窗口的,那么它会生生的弹出一个IE窗口来,而不是在内部跳到该链接。
如果使用Winform的WebBrowser控件,我们可以监听它的NewWindow事件,在这个事件中做一些处理,例如,在新建一个Tab来打开,或者控制它在当前WebBrowser中跳转。很不幸的是,WPF的WebBrowser没有这个事件。
说到底,Winform的WB或者是WPF的WB都是在调用IE的一个控件,因此,Winform能加上的,我们WPF一定也有办法加上。如此,那我们就请出神器Reflector,研究一把。
首先,我们打开Winform的WebBrowser,找到触发NewWindow事件的代码:- protected virtual void OnNewWindow(CancelEventArgs e)
- {
- if (this.NewWindow != null)
- {
- this.NewWindow(this, e);
- }
- }
复制代码 它是在OnNewWindow方法中触发的。那么,是谁调用了这个OnNewWindow呢?接着搜索,最后在一个叫 WebBrowserEvent的类里面发现这么一段:- public void NewWindow2(ref object ppDisp, ref bool cancel)
- {
- CancelEventArgs e = new CancelEventArgs();
- this.parent.OnNewWindow(e);
- cancel = e.Cancel;
- }
复制代码 我们接着搜NewWindow2,却发现没有地方显式地调用它了。既然从方法入手没找到,那我们就来研究一下定义这个方法的 WebBrowserEvent,看看是谁在使用它。 仔细搜索一遍,最后发现在WebBrowser的CreateSink方法中有这么一段:- protected override void CreateSink()
- {
- object activeXInstance = base.activeXInstance;
- if (activeXInstance != null)
- {
- this.webBrowserEvent = new WebBrowserEvent(this);
- this.webBrowserEvent.AllowNavigation = this.AllowNavigation;
- this.cookie = new AxHost.ConnectionPointCookie(activeXInstance, this.webBrowserEvent, typeof(UnsafeNativeMethods.DWebBrowserEvents2));
- }
- }
复制代码 注意这句话:- this.cookie = new AxHost.ConnectionPointCookie(activeXInstance, this.webBrowserEvent, typeof(UnsafeNativeMethods.DWebBrowserEvents2));
复制代码 很显然,这句话是关键。AxHost.ConnectionPointCookie类的作用是:“将一个ActiveX 控件连接到处理该控件的事件的客户端”。
|