WPF创建不规则窗体时WebBrowser控件不显示的问题

news/2024/11/16 7:56:16/文章来源:https://www.cnblogs.com/zhaotianff/p/18408345

最近有小伙伴需要在不规则窗体上放置WebBrowser控件,因为设置了WindowStyle="None" 和 AllowsTransparency="True"。

导致WebBrowser控件不显示。

 

界面如下所示:

 1 <Window x:Class="WebBrowserDemo.MainWindow"     
 3         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 4         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WebBrowserDemo"
 7         mc:Ignorable="d"
 8         Height="979" Width="1259"
 9         WindowStyle="None" ResizeMode="NoResize" Background="Transparent" AllowsTransparency="True"
10         MouseLeftButtonDown="Window_MouseLeftButtonDown" Loaded="Window_Loaded">
11     <Canvas>
12         <Image Source="background.png" Stretch="Fill" Width="1259" Height="979" />
13         <WebBrowser x:Name="webBrowser" Width="521" Height="635" Canvas.Left="58" Canvas.Top="198" Address="https://www.baidu.com" HorizontalAlignment="Left" VerticalAlignment="Center"></cef:ChromiumWebBrowser>
14     </Canvas>
15 </Window>

预期效果如下:

 

但实际浏览器并不会显示出来。

 

导致这个问题的原因是因为空域(airspace)问题,因为WebBrowser并不是一个原生的WPF控件,而是一个Win32控件。

详细描述可以参考以下两个链接:

https://learn.microsoft.com/en-us/archive/blogs/changov/webbrowser-control-on-transparent-wpf-window

https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/technology-regions-overview?view=netframeworkdesktop-4.8&redirectedfrom=MSDN

 

这里提供三个解决办法

1、将WebBrowser替换为CefSharp/WebView2等原生WPF控件

这种方法最简单,几乎不用修改什么代码,缺点是老版本系统可能不兼容。

 

2、使用WindowsChrome

1 <WindowChrome.WindowChrome>
2        <WindowChrome GlassFrameThickness="-1"/>
3 </WindowChrome.WindowChrome>

需要配合 ResizeMode="CanMinimize" Background="Transparent" WindowStyle="None" 使用

完整界面代码如下:

 1 <Window x:Class="WebBrowserDemo.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WebBrowserDemo"
 7         mc:Ignorable="d"
 8         ResizeMode="CanMinimize" Background="Transparent" WindowStyle="None" Height="979" Width="1259">
 9     <WindowChrome.WindowChrome>
10         <WindowChrome GlassFrameThickness="-1"/>
11     </WindowChrome.WindowChrome>
12     <Canvas>
13         <Canvas.Background>
14             <ImageBrush ImageSource="background.png" Stretch="Uniform"></ImageBrush>
15         </Canvas.Background>
16         <WebBrowser x:Name="webBrowser" Width="527" Height="501" Canvas.Left="54" Canvas.Top="249" Source="https://bing.com" HorizontalAlignment="Center" VerticalAlignment="Top"></WebBrowser>
17     </Canvas>
18 </Window>

 

3、将WebBrowser封装到一个独立的窗口,变成独立控件

这个方法来自stackoverflow上的一个老哥,链接如下:

https://stackoverflow.com/questions/23529824/how-do-i-work-around-the-activex-webbrowser-flaw-in-a-wpf-window-that-allowstran

 

首先我们新建一个Window

WebBrowserEx.xaml

 1 <Window x:Class="WebBrowserDemo.Controls.WebBrowserEx"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WebBrowserDemo.Controls"
 7         xmlns:winForms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"     
 8         WindowStyle="None"
 9         ShowInTaskbar="False"
10         ResizeMode="NoResize"  Width="761" Height="444">
11     <WindowsFormsHost x:Name="wfh">
12         <winForms:WebBrowser x:Name="wfBrowser" />
13     </WindowsFormsHost>
14 </Window>

 

后台代码如下:

WebBrowserEx.xaml.cs

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 using System.Windows;
  7 using System.Windows.Controls;
  8 using System.Windows.Data;
  9 using System.Windows.Documents;
 10 using System.Windows.Input;
 11 using System.Windows.Media;
 12 using System.Windows.Media.Imaging;
 13 using System.Windows.Shapes;
 14 
 15 namespace WebBrowserDemo.Controls
 16 {
 17     public partial class WebBrowserEx : Window
 18     {
 19         public WebBrowserEx()
 20         {
 21             InitializeComponent();
 22         }
 23 
 24         public static readonly DependencyProperty TargetElementProperty = DependencyProperty.Register("TargetElement", typeof(FrameworkElement), typeof(WebBrowserEx), new PropertyMetadata(TargetElementPropertyChanged));
 25         public FrameworkElement TargetElement
 26         {
 27             get
 28             {
 29                 return GetValue(TargetElementProperty) as FrameworkElement;
 30             }
 31             set
 32             {
 33                 SetValue(TargetElementProperty, value);
 34             }
 35         }
 36 
 37 
 38         public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(string), typeof(WebBrowserEx), new PropertyMetadata(SourcePropertyChanged));
 39         public string Source
 40         {
 41             get
 42             {
 43                 return GetValue(SourceProperty) as string;
 44             }
 45             set
 46             {
 47                 SetValue(SourceProperty, value);
 48             }
 49         }
 50         private static void SourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
 51         {
 52             var webBrowserOverlayWindow = sender as WebBrowserEx;
 53 
 54             if (webBrowserOverlayWindow != null)
 55             {
 56                 webBrowserOverlayWindow.wfBrowser.Navigate(args.NewValue as string);
 57             }
 58         }
 59 
 60         private static void TargetElementPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
 61         {
 62             var oldTargetElement = args.OldValue as FrameworkElement;
 63             var webBrowserOverlayWindow = sender as WebBrowserEx;
 64             var mainWindow = Window.GetWindow(webBrowserOverlayWindow.TargetElement);
 65 
 66             if (webBrowserOverlayWindow != null && mainWindow != null)
 67             {
 68                 webBrowserOverlayWindow.Owner = mainWindow;
 69                 webBrowserOverlayWindow.Owner.LocationChanged += webBrowserOverlayWindow.PositionAndResize;
 70                 webBrowserOverlayWindow.TargetElement.LayoutUpdated += webBrowserOverlayWindow.PositionAndResize;
 71 
 72                 if (oldTargetElement != null)
 73                     oldTargetElement.LayoutUpdated -= webBrowserOverlayWindow.PositionAndResize;
 74 
 75                 webBrowserOverlayWindow.PositionAndResize(sender, new EventArgs());
 76 
 77                 if (webBrowserOverlayWindow.TargetElement.IsVisible && webBrowserOverlayWindow.Owner.IsVisible)
 78                 {
 79                     webBrowserOverlayWindow.Show();
 80                 }
 81 
 82                 webBrowserOverlayWindow.TargetElement.IsVisibleChanged += (x, y) =>
 83                 {
 84                     if (webBrowserOverlayWindow.TargetElement.IsVisible && webBrowserOverlayWindow.Owner.IsVisible)
 85                     {
 86                         webBrowserOverlayWindow.Show();
 87                     }
 88                     else
 89                     {
 90                         webBrowserOverlayWindow.Hide();
 91                     }
 92                 };
 93             }
 94         }
 95 
 96         protected override void OnClosed(EventArgs e)
 97         {
 98             base.OnClosed(e);
 99 
100             Owner.LocationChanged -= PositionAndResize;
101             if (TargetElement != null)
102             {
103                 TargetElement.LayoutUpdated -= PositionAndResize;
104             }
105         }
106 
107         private void PositionAndResize(object sender, EventArgs e)
108         {
109             if (TargetElement != null && TargetElement.IsVisible)
110             {
111                 var point = TargetElement.PointToScreen(new Point());
112                 Left = point.X + 396;  //这里可以控制位置
113                 Top = point.Y + 326;   //point是左上角0,0的位置
114 
115                 //Height = TargetElement.ActualHeight;  //这里可以控制宽高
116                 //Width = TargetElement.ActualWidth;
117             }
118         }
119 
120     }
121 }

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/795500.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MUR2060CT-ASEMI快恢复二极管MUR2060CT

MUR2060CT-ASEMI快恢复二极管MUR2060CT编辑:ll MUR2060CT-ASEMI快恢复二极管MUR2060CT 型号:MUR2060CT 品牌:ASEMI 封装:TO-220AB 安装方式:插件 批号:最新 恢复时间:35ns 最大平均正向电流(IF):20A 最大循环峰值反向电压(VRRM):600V 最大正向电压(VF):0.95V~1…

多维度解析:为什么 Traefik 是云原生首选网关?

Hello folks,我是 Luga,今天我们来聊一下云原生生态领域相关的技术 - 云原生网关 Traefik 。 根据 Traefik Labs 团队对于 Traefik 在云原生生态中的定位:云原生反向代理和负载均衡器及网关解决方案。 — 01 — 从生态拥抱视角看:Traefik 的发展前景 从云原生生态视角来看,…

Adafactor Adaptive Learning Rates with Sublinear Memory Cost

目录概符号说明AdafactorFactored Second Moment EstimationNo MomentumOut-of-Date Second Moment Estimator算法代码Shazeer N. and Stern M. Adafactor: Adaptive learning rates with sublinear memory cost. ICML, 2018.概 本文介绍了一种 memory-efficient 的优化器: Ada…

Oracle 19c OCP 认证考试 082 题库(第19题)- 2024年修正版

【优技教育】Oracle 19c OCP 082题库(Q 19题)- 2024年修正版 考试科目:1Z0-082 考试题量:90 通过分数:60% 考试时间:150min 本文为(CUUG 原创)整理并解析,转发请注明出处,禁止抄袭及未经注明出处的转载。 原文地址:http://www.cuug.com.cn/ocp/082kaoshitiku/3822886061…

如何用 Helm 安装指定版本的 GitLab Runner?

本分分享如何使用 Helm 来在 Kubernetes 集群上安装极狐GitLab Runner。整体步骤分为:Helm 的安装、vaules.yaml 文件的配置、Runner 的安装、Runner 的测试。 极狐GitLab 为 GitLab 在中国的发行版,中文版本对中国用户更友好。极狐GitLab 支持一键私有化部署,可以在 ubuntu…

安装程序在安装此程序包时遇到了错误2503

原文链接:https://blog.csdn.net/sisi_new/article/details/139180294 安装程序在安装此程序包时遇到错误2503通常是由于安装权限不足造成的解决方案如下:1.修改TEMP文件夹的权限:进入“C:\Windows\Temp”路径,右键单击Temp文件夹选择“属性”,在“安全”选项卡中修改权限…

安全测试工具(1)- Burp Suite Pro的安装教程

啥是Burp Suite 用于攻击web 应用程序的集成平台 程序员必备技能,不仅可以拿来做渗透测试、漏洞挖掘还能帮助程序员调试程序 Bug 它包含了许多Burp工具,这些不同的burp工具通过协同工作,有效的分享信息,支持以某种工具中的信息为基础供另一种工具使用的方式发起攻击。这些工…

高等数学 1.6 极限存在准则 两个重要极限

目录第一个准则第一个重要极限第二个准则第二个重要极限柯西(Cauchy)极限存在准则 第一个准则 准则Ⅰ:如果数列 \(\{ x_n \}\) ,\(\{ y_n \}\) 及 \(\{ z_n \}\) 满足下列条件: (1)从某项起,即 \(\exists n_0 \in \mathbb{N}_+\) ,当 \(n > n_0\) 时,有 \[y_n \le…

socket套接字通信---win和linux互通(1)

一、Windows下的网络调试工具-NetAssist 下载页面 下载后无需安装,解压缩就是个exe的执行文件。双击打开就可使用 软件界面二、linux下的网络调试工具 nc(netcat) 1、当前系统 $ cat /proc/version Linux version 6.6.47-current-x86 (build@armbian) (gcc (Ubuntu 11.4.0-1u…

第一次编程作业

这个作业属于哪个课程 计科22级34班这个作业要求在哪里 个人项目这个作业的目标 1.设计一个查重算法。2. 了解并学习项目的PSP表格3. 学习如何运用github进行代码管理4. 学习使用性能分析工具,分析代码性能5. 学习如何进行单元测试我的github仓库链接:https://github.com/zfi…

mysql 拼接字段

select spot_position,req_line,CONCAT(spot_position,-,req_line) from pdm_qc_apply where req_qctype != 2;结果展示: