WPF WebBrowser 不可见问题的解析[转]
问题概述:
1.在Xaml中加入WebBrowser(不论是WPF中的控件,还是Winform中的控件)
2.设置Window Background="Transparent" AllowsTransparency="True"
结果:WebBroser中的内容将不可见。
问题分析:
本人当时一WPF菜鸟,根本无从下手。实乃WPF已广为人知的问题。原因很简单:
1.所谓WPF中的WebBrowser控件实为利用MS WebBrowser 经过WPF封装,其实质和Winform中的WebBrowser一样无非是加入了一些简单DependencyProperty,使其能够在Xaml中进行配置,其使用看起来和其他WPF控件一致。其内核仍是基于Win32。
2.明白了WPF/Winform 中WebBrowser控件的实质,我们进入主题,众所周知WPF所推崇的乃其划时代的图形渲染技术,这里不做展开。大家明白WPF采用矢量技术,消除了页面缩放过程中锯齿现象。因此WPF实现了于分辨率无关。但是Win32的渲染技术却非基于矢量技术。故WebBrowser的内在渲染和WPF有本质区别。
3.当我们设置Window Background="Transparent" AllowsTransparency="True" 以期实现玻璃窗口时WebBrowser不能完成WPF的渲染,因此出现如上所述WebBrowser内容不可见的问题。
结论:
不能将非WPF元素(例如基于Win32的控件)放入WPF中进行渲染,否则,基于Win32的控件将渲染失败,例如缩放失败,颜色渲染失败等等与矢量技术相关的属性设置。对于本章问题,若要混合使用基于Win32的控件和WPF控件,并且要设置
Window Background="Transparent" AllowsTransparency="True" 以实现多主体支持,应该将Win32元素放入Win32窗口,达到分开渲染的目的。
解决方案:
1.不要将WebBrowser直接在在Xaml中使用, 用以简单元素代替,如Canvas Grid Border等等Container皆可。用于定位
2.将WebBrowser,加为Form的child,自己封装,实现例如缩放等自定义功能。
3.在Window,初始化的时候,实例化经过Form封装的WebBrowser,并定位到步骤一中所述的Container。
Sample Code:
Xaml:
<Grid Name="IEcontainer" Grid.Column="0" Width="1006" Height="577"/>
WebBrowser封装:
static class Win32
{
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
.......
[DllImport("user32.dll")]
internal static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint);
[DllImport("user32.dll")]
internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth,int nHeight, bool bRepaint);
};
class WebBrowserOverlayWF
{
Window _owner;
FrameworkElement _placementTarget;
Form _form; // the top-level window holding the WebBrowser control
WebBrowser _wb = new WebBrowser();
.......................
public WebBrowserOverlayWF(FrameworkElement placementTarget)
{
_placementTarget = placementTarget;
Window owner = Window.GetWindow(placementTarget);
_owner = owner;
_form = new Form();
_form.ShowInTaskbar = false;
_form.FormBorderStyle = FormBorderStyle.None;
_wb.Dock = DockStyle.Fill;
_form.Controls.Add(_wb);
_wb.ScrollBarsEnabled = false;
owner.SizeChanged += delegate { OnSizeLocationChanged(); };
owner.LocationChanged += delegate { OnSizeLocationChanged(); };
_placementTarget.SizeChanged += delegate { OnSizeLocationChanged(); };
if (owner.IsVisible)
InitialShow();
else
owner.SourceInitialized += delegate{InitialShow(););
..........
}
void InitialShow()
{
NativeWindow owner = new NativeWindow();
owner.AssignHandle(
((HwndSource)HwndSource.FromVisual(_owner)).Handle);
_form.Show(owner);
owner.ReleaseHandle();
}
...............
}
Window Loaded:
WebBrowserOverlayWF wbo = new WebBrowserOverlayWF(IEcontainer);
拓展:
上例中演示了如何将基于Win32的控件封装到WPF中,实现了缩放,和重定位的功能(篇幅限制,如需具体代码,请联系本人)。其实我们无意中已经涉及到了控件的封装和重写。今后将陆续和大家分享更多WPF控件封装和重写的技术。
原文: http://hi.baidu.com/leo_han/item/cd1debbf4dfbb3462bebe30a
WPF WebBrowser 不可见问题的解析[转]的更多相关文章
- WPF WebBrowser屏蔽弹出alert ,confirm ,prompt ,showModalDialog() ,window.open()
WPF WebBrowser屏蔽弹出alert ,confirm ,prompt ,showModalDialog() ,window.open()添加Microsoft.mshtml.dll,然后写 ...
- vb.net WPF webbrowser window.close 关闭后不触发 WindowClosing 事件 WNDPROC解决方式
vb.net WPF webbrowser window.close 关闭后不触发 WindowClosing 事件 WNDPROC解决方式 #Region "WPF 当浏览器窗体关闭 ...
- WPF WebBrowser Memory Leak 问题及临时解决方法
首先介绍一下内存泄漏(Memory Leak)的概念,内存泄露是指程序中已动态分配的堆内存由于某种原因未释放或者无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果. 最近在使用W ...
- WPF WebBrowser+TabControl MVVM模式 简单应用 提供源码下载
源代码下载 这个程序是TabControl和Webbrowser的练手小程序 可达到练手目的有: MVVM设计模式的基本使用 Binding(包括相对源[RelativeSource]绑定)的基本使用 ...
- WPF:WebBrowser提示 为帮助保护你的安全,您的Web浏览器已经限制此文件显示可能访问您的计算机的活动内容
原文:WPF:WebBrowser提示 为帮助保护你的安全,您的Web浏览器已经限制此文件显示可能访问您的计算机的活动内容 版权声明:本文为博主原创文章,未经博主允许可以随意转载 https://bl ...
- 捕捉WPF应用程序中XAML代码解析异常
原文:捕捉WPF应用程序中XAML代码解析异常 由于WPF应用程序中XAML代码在很多时候是运行时加载处理的.比如DynamicResource,但是在编译或者运行的过程中,编写的XAML代码很可能有 ...
- wpf Webbrowser 乱码问题及弹窗被遮挡
wpf的webbrowser在使用NavigateToString(string text);方法时如果字符串含有中文字符,并在html的头文件中没有声明Document的编码方式为UTF-8的话,由 ...
- WPF快速入门系列(3)——深入解析WPF事件机制
一.引言 WPF除了创建了一个新的依赖属性系统之外,还用更高级的路由事件功能替换了普通的.NET事件. 路由事件是具有更强传播能力的事件——它可以在元素树上向上冒泡和向下隧道传播,并且沿着传播路径被事 ...
- WPF快速入门系列(2)——深入解析依赖属性
一.引言 感觉最近都颓废了,好久没有学习写博文了,出于负罪感,今天强烈逼迫自己开始更新WPF系列.尽管最近看到一篇WPF技术是否老矣的文章,但是还是不能阻止我系统学习WPF.今天继续分享WPF中一个最 ...
随机推荐
- 卡特兰数(Catalan Number) 算法、数论 组合~
Catalan number,卡特兰数又称卡塔兰数,是组合数学中一个常出现在各种计数问题中出现的数列.以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)命名. 卡特兰数的前几个数 前20项为( ...
- 【算法入门】广度/宽度优先搜索(BFS)
广度/宽度优先搜索(BFS) [算法入门] 1.前言 广度优先搜索(也称宽度优先搜索,缩写BFS,以下采用广度来描述)是连通图的一种遍历策略.因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较 ...
- 如何理解这段代码:void (*signal (int sinno,void(*func)(int)))(int)
void (*signal (int sinno,void(*func)(int)))(int) 先来看void(*func)(int) 这里的意思是声明一个函数指针func,它的参数类型为int ...
- 让x86的android模拟器能模拟arm架构系统
网上介绍共计三种模拟器比较常用,分别是bluestacks.andy和Genymotion,前者支持ARM架构,中者支持远程控制,后者启动速度快,各有优缺点. 如果要用genymotion模拟arm的 ...
- TreeView设置节点图标
TreeView设置节点图标 没子节点的设置其图标为 0 有节点的设置其图标为 1 procedure TForm1.Button1Click(Sender: TObject);var i:Int ...
- /var/log目录下的20个Linux日志文件功能详解 分类: 服务器搭建 linux内核 Raspberry Pi 2015-03-27 19:15 80人阅读 评论(0) 收藏
如果愿意在Linux环境方面花费些时间,首先就应该知道日志文件的所在位置以及它们包含的内容.在系统运行正常的情况下学习了解这些不同的日志文件有助于你在遇到紧急情况时从容找出问题并加以解决. 以下介绍的 ...
- 在GDB 中如何记录 instruction-history and function-call-history
(EDIT: per the first answer below the current "trick" seems to be using an Atom processor. ...
- java按照集合中元素的属性进行排序示例代码
public class Student { private String name; private int age; private int id; public Student() { sup ...
- Bginfo软件在域的部署和应用
在企业的IT管理中,很多用户都不知道怎么去查看自己计算机的IP地址.登陆帐户.而对于网络管理人员来说,他们可能需要知道用户在域中登录的一些信息,如那些用户登录过,在什么时间登录,IP和MAC地址是多少 ...
- Ant工具
Ant工具 Ant是一种基于Java的build工具.理论上来说,它有些类似于(Unix)C中的make ,但没有make的缺陷.目前的最新版本为:Ant 1.9.4[1] . Ant的概念 当一 ...