注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

分享,态度 ·~~

—— 十年太长,五年;如果可以回到五年前,你最想对那时候的自己说什么?

 
 
 

日志

 
 

WindowsFormsHost  

2010-03-16 16:00:13|  分类: DotNet |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

在WPF中使用传统的WinForm控件时,需要用一个叫WindowsFormsHost的WPF控件将WinForm控件包裹起来,以实现WPF控件和WinForm控件的混合使用。如下:

<DockPanel>
   
<my:WindowsFormsHost>
      
<swf:WebBrowser Name="vvv"></swf:WebBrowser>
   
</my:WindowsFormsHost>
</DockPanel>

WindowsFormsHost包裹了一个WebBrowser控件(swf:System.Windows.Forms)。问题来了,在写WebBrowser的Navigated事件代码时,遇到问题:

void currentBrowser_Navigated(object sender, swf.WebBrowserNavigatedEventArgs e)
{
    swf.WebBrowser currentBrowser 
= sender as swf.WebBrowser;
    swf.Control host 
= currentBrowser.Parent;
    DockPanel dockPanel 
= host.Parent as DockPanel;
    
//some other work
}

执行程序,结果:"host.Parent as DockPanel"报错:不能将WinForm控件转换为WPF的DockPanel控件!

断点调试,结果:发现host.Parent属性是一个WinFormsAdapter的类型,不是WindowsFormsHost。

修改代码:WinFormsAdapter adapter = host.Parent as WinFormsAdapter;结果:继续报错:系统无法识别WinFormsAdapter。

引入名字空间:using System.Windows.Forms.Integration;结果:还是报错,系统依然无法识别。

到此,整个人的情绪是这个样子的:

寻找WindowsFormsHost的困难之旅于是开始了!

google一次:"how to get the parent control WindowsFormsHost",结果:有讨论,没答案!(在这里消耗了大把大把的time)

google二次:"WinFormsAdapter",结果:它是一个internal class。怪不得无法识别!(微软为什么要这么做呢?希望有高手能分析分析)

ildasm:截图如下:

WinFormsAdapter 

发现:构造函数.ctor:void(class System.Windows.Forms.Integration.WindowsFormsHost)的参数想必就是我们的WindowsFormsHost,而从类型和命名上判断,变量_host在构造函数中存储了这个数据。

到此终于可以放松些了,虽然问题解决了,但始终还是很疑惑,为什么这个WinFormsAdapter要设计成internal,而且通过ildasm还发现_host作为私有变量也没有属性(Property)封装。微软在WindowsFormsHost中设计了Child属性以便向下寻找WinForm,那应该会考虑到人家WinForm向上寻找WPF啊,这样internal一下,再private一下,是何用意?

WinFormsAdapter有什么不可告人的秘密,不便公开?我想没必要!

或者微软提供了其他的更好的办法,不建议使用WinFormsAdapter,所以藏起来?见鬼,对树(包括WPF的逻辑树)的操作习惯就是这样的,是长期以来形成的,别的办法哪怕更好,这个因素你也得考虑一下啊,还可不是一个人的问题。

希望能有达人出现,分析分析这个问题,或者提出更好的办法!

最后把反射部分的代码附上:

    swf.WebBrowser currentBrowser = sender as swf.WebBrowser;    
    swf.Control adapter 
= currentBrowser.Parent;

    Assembly asm 
= typeof(WindowsFormsHost).Assembly;
    Type type 
= asm.GetType("System.Windows.Forms.Integration.WinFormsAdapter");
    
object parent = type.InvokeMember("_host",
        BindingFlags.NonPublic 
| BindingFlags.GetField | BindingFlags.Instance,
        
null,
        adapter,
        
new Object[] { });
    WindowsFormsHost host 
= parent as WindowsFormsHost;
    DockPanel dockPanel 
= host.Parent as DockPanel;
 

结束!

【from 武汉虫虫 http://www.cnblogs.com/notgg/archive/2009/11/25/1610333.html

  评论这张
 
阅读(3044)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017