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>
网上找了各种资料,发现:
若设置窗体为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>
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 }
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>
4.需要使用的cs文件中添加代码:
var w = new WebBrowserOverlay(this.BdBrowser); var wb = w.WebBrowser; var HelpUrl = "http://www.baidu.com"; wb.Navigate(new System.Uri(HelpUrl));