解决 WPF 自绘窗体 AllowsTransparency = true 和 Webbrowser 等内置窗体显示冲突的办法和思路
来源:互联网 发布:nba纳什数据 编辑:程序博客网 时间:2024/05/26 02:20
示例代码在这里:http://download.csdn.net/source/2731942
上述示例程序的几个关键点:
- WPF 窗体为主窗体,窗体风格为 AllowsTransparency = true
- 分别对主窗体内置 WPF 的 Webbrowser 控件和 Winform 的 Webbrowser 控件进行了演示
- 完美的窗体缩放、移动、最大化等操作
- 演示随意调整窗体背景透明度
- 示例代码简单易操作,是可以找得到的最完美,而且的确是完美的解决办法
山寨关键点
一、关键代码如下:
WPF
WebBrowserOverlay wbo = new WebBrowserOverlay(_webBrowserPlacementTarget);
System.Windows.Controls.WebBrowser wb = wbo.WebBrowser;
wb.Navigate(new Uri(“http://blog.csdn.net/hikaliv/”));Winform
WebBrowserOverlayWF wbo = new WebBrowserOverlayWF(_webBrowserPlacementTarget);
System.Windows.Forms.WebBrowser wb = wbo.WebBrowser;
wb.Navigate(new Uri(“http://blog.csdn.net/hikaliv”));
这两段代码分别是你在程序里面安置 WPF 的 Webbrowser 控件或 Winform 的 Webbrowser 控件的方法——关键在你不能放错地方。注意:代码你只能放在主窗体的构造函数处,InitializeComponent() 方法之后。
二、别忘了在工程 References 里面添加 System.Windows.Presentation.dll,若要用到 Winform 的控件,还需要添加 System.Windows.Forms.dll 引用。
三、不得设置 WindowStartupLocation 属性。
这不是我的方法和示例代码,这是微软工程师的方法和示例代码,详见我转载他们的几篇关键文章:
1、《WebBrowser control on transparent WPF window》
2、《Transparent Windows in WPF》
3、《Technology Regions Overview》
此示例完整地诠释了一种最可取的办法——在主窗体上划出一块区域,由一块 FrameworkELement Object 的可视域(CompositionTarget)来呈现浏览器控件所属的顶级窗体——重点是这个“顶级窗体(Top-Level Window)”——以实现”视觉上”浏览器“内嵌”在主窗体。
此法三个关键点用红字标出。这三个关键点也道出了此法作为最可取之法——其实也是唯一可取之法的原因。或许还有其它办法,但效果一定都不理想,灵活性也差。最终的效果是需要“视觉上内嵌”,而事实上并不需要逻辑上内嵌——因为逻辑内嵌的结果是不想要的,否则也不会有这个困难了。这个问题出现的关键在于上面第三篇文章介绍的内容,还有一点是 WPF(DirectX)和 Win32(GDI)的渲染顺序——其实这些倒并不恶心,真正恶心的地方在于 Webbrowser 这个控件……你会发现 template 对它无用,而且用你能找到的最强大的内查工具看它是铅板一块,透视不得。WPF 的 Webbrowser 到底是个什么神秘的东西需要这么保密?——不仅神秘,而且古老——关键是古老,Winform 和 WPF 其实都没有对它进行重写以使它至少在 UI 上可以更强大,不,不仅 UI 体验上没有加强,而且事实功能上反而一代比一代更加弱小——建议大伙儿彻底放弃 system.windows.controls.webbrowser 好了,当它根本没存在过,视而不见,只用 system.windows.forms.webbrowser,或者直接用 MFC 的,反正只不过需要加层 WindowsHost 或者 HWNDSOURCE 而已。
正因为 Webbrowser 的恶心,因此唯一正确的思路则是必须将它和 WPF 主窗体逻辑解体。否则只能取缔 WPF 窗体的 AllowsTransparency = true 属性约束,使 WPF 的 Transparent/Alpha 通道渲染和这个控件的底层渲染不冲突。想闯闯没有 AllowsTransparency = true 属性约束的 WPF 自制窗体吗?自己去处理无尽的 WINDOWS MESSAGE 麻烦吧——友情提示一声—— WPF 渲染和系统(GDI)渲染是两层,截消息的办法是行不通的……如果你还想再架层 DWM 渲染的话……祝你被愉快。
总之,WPF 自制窗体“内嵌”Webbrowser 控件必须的两点:
- AllowsTransparency = true。这简简单单一句话……其实背后的水很深很深……没它你试试……
- 控件与主窗体必须逻辑解体。
问题症结
一句话概括就是“窗体的逻辑和渲染冲突”。我不知道非 WIN 系统是否会存在这个问题,然而在 WINDOWS 系统上,这是一个很恶心的问题。而且这也并非是个案,因为说得不好听点儿,这根本就是版本间不可兼容的事儿,是微软产品的通病。我不了解 Apple 的 MAC 系统是如何渲染的,但我体会到了 WPF 渲染的代价——这么多层、重复渲染、渲染冲突,而且还不如 MAC 的效果好,对硬件宽容,性能高……唉……
抱怨一下,为何微软的 WPF 开发团队这么“懒”呢?把 system.windows.controls.webbrowser 写得比 system.windows.forms.webbrowser 要差,残废,而且 WPF 下面的 Datagrid 也远不如 Winform 的 Datagridview。MS 平台软件开发的方向,从 MFC 的实打实,经过 Winform 越来越向 WPF 的华而不实的方向走……WPF 确立了一种全新的窗体组织形式,让 UI 和控件开发实现了松耦合、自动化,但不能用实用性的缺失为交换。记得 .net framework 刚出来的时候,全新的 C#.net 体验让学长传达给我他在微软工程院从工程师那里听到的一句话——MFC 的末日到了……效率不效率的其实并非重点,重点是新框架下的控件比旧框架下的控件不实用……那又如何宣判得了旧框架的死刑呢?
- 解决 WPF 自绘窗体 AllowsTransparency = true 和 Webbrowser 等内置窗体显示冲突的办法和思路
- WPF窗体动画显示和关闭
- 解决窗体靠边自动隐藏和最小化后恢复窗体的冲突
- wpf 子窗体和父窗体的通信
- WPF和Winform拖动窗体
- 父窗体和子窗体的显示(vb.net)
- C# 窗体程序界面显示和操作word 单是不依赖office的操作办法
- WinForm窗体显示和窗体间传值总结
- WinForm窗体显示和窗体间传值总结
- WinForm窗体显示和窗体间传值
- WinForm窗体显示和窗体间传值
- WinForm窗体显示和窗体间传值总结
- WPF窗体全屏显示
- WPF窗体居中显示
- 理解windows 窗体和wpf的跨线程调用
- WPF窗体最大化、最小化、关闭按钮的隐藏和禁用
- Delphi显示和隐藏窗体
- -创建和显示窗体实例
- 嵌入式linux与ARM开发板的入门建议
- 从 Delphi 7 到 Delphi 2010
- windows系统下JDK1.6环境变量配置
- Hdfs-Raid tools文档翻译
- 人民币大写的正确写法(开票据事项)
- 解决 WPF 自绘窗体 AllowsTransparency = true 和 Webbrowser 等内置窗体显示冲突的办法和思路
- 动态添加Table
- 无奈
- D3D,一个平面,正反面进行纹理映射
- 上手haskell没有不痛苦的!
- 程序员:下一次面试前你需要准备的五个基本步骤
- C++文件读写
- 我的博客
- maven做调试的烦恼