打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
WPF WebBrowser 不可见问题的解析
WPF WebBrowser 不可见问题的解析
2010年09月08日 星期三 12:51

问题概述:

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控件封装和重写的技术。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
【思维导图】新手该怎么学习C#/WPF
WPF——XAML文件的格式
WPF中AllowsTransparency和WebBrowser兼容性问题
WPF学习与分享之一: WPF与WinForm比较
WPF 与网页交互(Frame,WebBrowser)(
WPF关于WindowInteropHelper的一个BUG
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服