You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决UWP项目中WebView2切换可见性时的闪烁问题?

UWP中WebView2切换可见性时的闪烁问题解决建议

在UWP项目中,某页面包含多个子页面,其中一个子页面使用Microsoft.UI.Xaml.Controls.WebView2控件打开一次链接(如www.bing.com)。完成网页导航后切换到其他子页面再返回时,WebView2内容会出现从黑屏到网页内容的闪烁,该问题由WebView2可见性变化导致。

现有代码

XAML

<Page
    x:Class="WebView2FlickerDemo.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:WebView2FlickerDemo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:controls="using:Microsoft.UI.Xaml.Controls"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <Button Click="Button_Click" Width="200" Height="100"></Button>

        <controls:WebView2 x:Name="WebView2" Height="567.55" Width="792" Margin="200 150 0 0" Visibility="Visible"/>
        <Grid x:Name="myGrid" Background="Blue" Height="567.55" Width="792" Margin="200 150 0 0" Visibility="Collapsed"></Grid>
    </Grid>
</Page>

C#

public MainPage()
{
    this.InitializeComponent();
    StartWebView2();
}

private async void StartWebView2()
{
    try
    {
        await WebView2.EnsureCoreWebView2Async();
        WebView2.CoreWebView2.Navigate("https://www.bing.com");
    }
    catch (Exception ex)
    {
    }
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    if (WebView2.Visibility == Visibility.Visible)
    {
        WebView2.Visibility = Visibility.Collapsed;
        myGrid.Visibility = Visibility.Visible;
    }
    else if (WebView2.Visibility == Visibility.Collapsed)
    {
        WebView2.Visibility = Visibility.Visible;
        myGrid.Visibility = Visibility.Collapsed;
    }
}

解决建议

方案1:用Opacity+IsHitTestVisible替代Visibility控制显示

直接设置Visibility=Collapsed会销毁WebView2的内部渲染状态,切换回来时需重新初始化导致闪烁。改用透明度和交互性控制,保持控件始终处于加载状态:

修改XAML初始状态:

<controls:WebView2 x:Name="WebView2" Height="567.55" Width="792" Margin="200 150 0 0" Opacity="1" IsHitTestVisible="True"/>
<Grid x:Name="myGrid" Background="Blue" Height="567.55" Width="792" Margin="200 150 0 0" Opacity="0" IsHitTestVisible="False"/>

修改C#点击事件:

private void Button_Click(object sender, RoutedEventArgs e)
{
    if (WebView2.Opacity == 1)
    {
        WebView2.Opacity = 0;
        WebView2.IsHitTestVisible = false;
        myGrid.Opacity = 1;
        myGrid.IsHitTestVisible = true;
    }
    else
    {
        WebView2.Opacity = 1;
        WebView2.IsHitTestVisible = true;
        myGrid.Opacity = 0;
        myGrid.IsHitTestVisible = false;
    }
}

方案2:通过Canvas.ZIndex控制层级覆盖

保持WebView2始终可见,调整层级让其他子页面覆盖在它上方,避免控件进入隐藏状态:

修改XAML:

<controls:WebView2 x:Name="WebView2" Height="567.55" Width="792" Margin="200 150 0 0" Canvas.ZIndex="0"/>
<Grid x:Name="myGrid" Background="Blue" Height="567.55" Width="792" Margin="200 150 0 0" Canvas.ZIndex="1"/>

修改C#点击事件:

private void Button_Click(object sender, RoutedEventArgs e)
{
    if (WebView2.Canvas.ZIndex == 0)
    {
        WebView2.Canvas.ZIndex = 2;
        myGrid.Canvas.ZIndex = 1;
    }
    else
    {
        WebView2.Canvas.ZIndex = 0;
        myGrid.Canvas.ZIndex = 1;
    }
}

方案3:缓存WebView2快照过渡

首次加载完成后截取WebView2内容快照,切换回来时先显示快照,待控件完全渲染后再切换回原控件:

在C#中添加快照逻辑:

private WriteableBitmap _webViewSnapshot;

private async void StartWebView2()
{
    try
    {
        await WebView2.EnsureCoreWebView2Async();
        WebView2.CoreWebView2.Navigate("https://www.bing.com");
        WebView2.CoreWebView2.NavigationCompleted += CoreWebView2_NavigationCompleted;
    }
    catch (Exception ex)
    {
    }
}

private async void CoreWebView2_NavigationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationCompletedEventArgs e)
{
    if (e.IsSuccess)
    {
        var renderTargetBitmap = new RenderTargetBitmap();
        await renderTargetBitmap.RenderAsync(WebView2);
        _webViewSnapshot = new WriteableBitmap(renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight);
        using (var stream = _webViewSnapshot.PixelBuffer.AsStream())
        {
            await renderTargetBitmap.PixelBuffer.CopyToAsync(stream);
        }
    }
}

XAML新增快照显示控件:

<Image x:Name="WebViewSnapshotImg" Height="567.55" Width="792" Margin="200 150 0 0" Visibility="Collapsed"/>

修改点击事件:

private void Button_Click(object sender, RoutedEventArgs e)
{
    if (WebView2.Visibility == Visibility.Visible)
    {
        WebView2.Visibility = Visibility.Collapsed;
        myGrid.Visibility = Visibility.Visible;
    }
    else
    {
        WebViewSnapshotImg.Source = _webViewSnapshot;
        WebViewSnapshotImg.Visibility = Visibility.Visible;
        myGrid.Visibility = Visibility.Collapsed;
        
        Task.Delay(100).ContinueWith(t =>
        {
            Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                WebViewSnapshotImg.Visibility = Visibility.Collapsed;
                WebView2.Visibility = Visibility.Visible;
            });
        });
    }
}

内容的提问来源于stack exchange,提问作者Tom Xue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 18:07:53