miketwais

work up

WPF内嵌WebBrowser不显示问题

WPF项目中需要在 Windows上做出透明效果,加上透明效果后,莫名其妙的windows上内嵌的WebBrowser就消失不见了。

windows的样式代码如下:

 1 <Style x:Key="faq_window" TargetType="Window">
 2         <Setter Property="AllowsTransparency" Value="true"/>
 3         <Setter Property="Background" Value="Transparent"/>
 4         <Setter Property="FontFamily" Value="Microsoft YaHei Light"/>
 5         <Setter Property="FontSize" Value="14"/>
 6         <Setter Property="ResizeMode" Value="NoResize"/>
 7         <Setter Property="WindowStyle" Value="None"/>
 8         <Setter Property="Template">
 9             <Setter.Value>
10                 <ControlTemplate TargetType="{x:Type Window}">
11                     <Grid Margin="8">
12                         <Border BorderBrush="#6F666666" BorderThickness="1" Background="White" 
13         SnapsToDevicePixels="True">
14                             <Border.Effect>
15                                 <DropShadowEffect ShadowDepth="0" BlurRadius="10"/>
16                             </Border.Effect>
17                             <ContentPresenter />
18                         </Border>
19                     </Grid>
20                 </ControlTemplate>
21             </Setter.Value>
22         </Setter>
23     </Style>
View Code

 

网上找了各种资料,发现:

若设置窗体为AllowsTransparency="True",WindowStyle="None",内嵌的WebBrowser就无法显示了,但它加载的网页内容还能正常交互。

所以,这是个无法解决的问题?网友给了一种解决方法,经过测试是可以的,这里记录下。

整体思路是这样的:我们自己创建一个窗体,然后初始化的时候,我们去寻找原窗体,计算窗体的大小(宽,高),和位置,然后将我们创建的窗体放到原来的webbrowser上。

1.创建文件:WebBrowserOverlay.xaml

1 <Window x:Class="operateToolWPF.Controls.WebBrowserOverlay"
2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4         WindowStyle="None" ShowInTaskbar="False" ResizeMode="NoResize" Background="Transparent" Opacity="0"  >
5     <WebBrowser Name="_wb">
6 
7     </WebBrowser>
8 </Window>  
View Code

2.创建文件:WebBrowserOverlay.xaml.cs

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Diagnostics;
  4 using System.Linq;
  5 using System.Runtime.InteropServices;
  6 using System.Text;
  7 using System.Windows;
  8 using System.Windows.Controls;
  9 using System.Windows.Data;
 10 using System.Windows.Documents;
 11 using System.Windows.Input;
 12 using System.Windows.Interop;
 13 using System.Windows.Media;
 14 using System.Windows.Media.Imaging;
 15 using System.Windows.Shapes;
 16 
 17 
 18 namespace myWPF.Controls
 19 {
 20     /// <summary>
 21     /// WebBrowserOverlay.xaml 的交互逻辑
 22     /// </summary>
 23     public partial class WebBrowserOverlay : Window
 24     {
 25         FrameworkElement _placementTarget;
 26 
 27 
 28         public WebBrowser WebBrowser { get { return this._wb; } }
 29 
 30         
 31         public WebBrowserOverlay(FrameworkElement placementTarget)
 32         {
 33             InitializeComponent();
 34 
 35             //_wb = WebBrowser;
 36             _placementTarget = placementTarget;
 37             Window owner = Window.GetWindow(placementTarget);
 38             Debug.Assert(owner != null);
 39             //Owner = owner;
 40             //owner.SizeChanged += delegate { OnSizeLocationChanged(); };  
 41             owner.LocationChanged += delegate { OnSizeLocationChanged(); };
 42             _placementTarget.SizeChanged += delegate { OnSizeLocationChanged(); };
 43 
 44 
 45             if (owner.IsVisible)
 46             {
 47                 Owner = owner;
 48                 //OnSizeLocationChanged();
 49                 Show();
 50             }
 51             else
 52                 owner.IsVisibleChanged += delegate
 53                 {
 54                     if (owner.IsVisible)
 55                     {
 56                         Owner = owner;
 57                         Show();
 58                     }
 59                 };
 60 
 61 
 62             //owner.LayoutUpdated += new EventHandler(OnOwnerLayoutUpdated);  
 63         }
 64 
 65 
 66         protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
 67         {
 68             base.OnClosing(e);
 69             if (!e.Cancel)
 70                 // Delayed call to avoid crash due to Window bug.  
 71                 Dispatcher.BeginInvoke((Action)delegate
 72                 {
 73                     Owner.Close();
 74                 });
 75         }
 76 
 77 
 78         void OnSizeLocationChanged()
 79         {
 80             if (Owner != null)
 81             {
 82                 Point offset = _placementTarget.TranslatePoint(new Point(), Owner);
 83                 Point size = new Point(_placementTarget.ActualWidth, _placementTarget.ActualHeight);
 84                 HwndSource hwndSource = (HwndSource)HwndSource.FromVisual(Owner);
 85                 CompositionTarget ct = hwndSource.CompositionTarget;
 86                 offset = ct.TransformToDevice.Transform(offset);
 87                 size = ct.TransformToDevice.Transform(size);
 88 
 89 
 90                 Win32.POINT screenLocation = new Win32.POINT(offset);
 91                 Win32.ClientToScreen(hwndSource.Handle, ref screenLocation);
 92                 Win32.POINT screenSize = new Win32.POINT(size);
 93 
 94                 //问题:(HwndSource)HwndSource.FromVisual(this)为null
 95                 Win32.MoveWindow(((HwndSource)HwndSource.FromVisual(this)).Handle, screenLocation.X, screenLocation.Y, screenSize.X, screenSize.Y, true);
 96                 //Win32.MoveWindow(((HwndSource)HwndSource.FromVisual(WebBrowserOverlay this)).Handle, screenLocation.X, screenLocation.Y, screenSize.X, screenSize.Y, true);
 97             }
 98             
 99         }
100     }
101     static class Win32
102     {
103         [StructLayout(LayoutKind.Sequential)]
104         public struct POINT
105         {
106             public int X;
107             public int Y;
108 
109             public POINT(int x, int y)
110             {
111                 this.X = x;
112                 this.Y = y;
113             }
114             public POINT(Point pt)
115             {
116                 X = Convert.ToInt32(pt.X);
117                 Y = Convert.ToInt32(pt.Y);
118             }
119         };
120 
121         [DllImport("user32.dll")]
122         internal static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint);
123 
124         [DllImport("user32.dll")]
125         internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
126     }
127 }
View Code

3.在你需要使用的xaml中添加下面代码:

<Border x:Name="BdBrowser" Margin="0,30,0,0">
                    <WebBrowser x:Name="show_help" Panel.ZIndex="111" Canvas.Left="0" Canvas.Top="32" Width="610" Height="385" Visibility="Hidden" IsHitTestVisible="False" LoadCompleted="show_help_LoadCompleted" />
                </Border>
View Code

4.需要使用的cs文件中添加代码:

var w = new WebBrowserOverlay(this.BdBrowser);
var wb = w.WebBrowser;
var HelpUrl = "http://www.baidu.com";
wb.Navigate(new System.Uri(HelpUrl));
View Code

 

posted @ 2018-01-26 15:18  MasonZhang  阅读(4940)  评论(4编辑  收藏  举报