如何在WPF Window中设置WebView2控件的圆角效果
问题原因
WebView2属于HwndHost派生的寄宿控件,本质是在WPF窗口上叠加了一个独立的Win32子窗口,WPF的默认裁剪、圆角属性不会作用于独立的Win32窗口,所以会出现内容溢出的情况。
可行实现方案
方案一:透明背景配合圆角遮罩(兼容性最好,Win10 1809+可用)
- 首先修改WebView2的默认背景为透明,同时叠加一个和窗口背景同色的圆角边框作为遮罩层,遮住WebView2的尖角部分。
修改后的XAML示例:
<Window x:Class="Webview2Experiment.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Webview2Experiment" xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf" mc:Ignorable="d" Title="MainWindow" Height="450" Width="400" WindowStyle="None" AllowsTransparency="True" Background="Transparent"> <Grid> <!-- WebView2承载层 --> <Border CornerRadius="22" Background="White"> <wv2:WebView2 Name="webView2" Width="400" Height="450" DefaultBackgroundColor="Transparent"/> </Border> <!-- 圆角遮罩层:边框宽度等于圆角半径,必须关闭命中测试否则会拦截操作 --> <Border CornerRadius="22" BorderBrush="Transparent" BorderThickness="22" IsHitTestVisible="False"/> </Grid> </Window>
- 在WebView2的页面加载完成后注入CSS,让页面本身也适配圆角裁剪,避免页面背景溢出:
C#后台代码示例:
public MainWindow() { InitializeComponent(); webView2.NavigationCompleted += WebView2_NavigationCompleted; } private async void WebView2_NavigationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationCompletedEventArgs e) { await webView2.CoreWebView2.ExecuteScriptAsync(@" document.body.style.borderRadius = '22px'; document.body.style.overflow = 'hidden'; document.documentElement.style.borderRadius = '22px'; document.documentElement.style.overflow = 'hidden'; "); }
方案二:设置窗口裁剪区域(适合不需要透明窗口的场景)
如果不需要窗口透明效果,可以直接调用Win32 API给整个窗口设置圆角裁剪区域,直接切掉WebView2的尖角部分:
protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); IntPtr hwnd = new WindowInteropHelper(this).Handle; // 圆角直径为22*2=44 IntPtr hRgn = CreateRoundRectRgn(0, 0, (int)Width, (int)Height, 44, 44); SetWindowRgn(hwnd, hRgn, true); } // 导入所需Win32 API [DllImport("gdi32.dll")] public static extern IntPtr CreateRoundRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse); [DllImport("user32.dll")] public static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
注意事项
- 方案一的遮罩层颜色必须和窗口所处的父容器/桌面背景完全一致,否则会露出边框痕迹,不规则背景场景优先使用方案二。
- 如果加载的是不可控的第三方网页,注入CSS的方式可能被页面自身样式覆盖导致失效,优先选择方案二的窗口裁剪方式。
内容的提问来源于stack exchange,提问作者tahiat
相关产品推荐
相关产品推荐

