• 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

  • 相关阅读:
    poj3660 最短路/拓扑序
    poj1502 最短路
    poj3259 最短路判环
    poj1680 最短路判环
    一些自己常用的cdn
    bower
    vuejs点滴
    jquery的ajax
    jquery点滴
    githubpage+hexo构建自己的个人博客
  • 原文地址:https://www.cnblogs.com/xiangfeideshui/p/3997977.html
Copyright © 2020-2023  润新知