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

.NET MAUI Windows端自定义WebView无法加载内容问题

.NET MAUI Windows WebView自定义渲染器加载失败问题修复

问题根源分析

  • CoreWebView2未就绪:WebView2控件必须完成核心组件初始化才能正常加载内容,直接设置Source或调用NavigateToString会因核心组件未启动而静默失败。
  • 异步流程不规范:LoadHtml使用async void定义,未等待异步操作完成,导致初始化逻辑中断。
  • 错误事件未实现:仅注册了CoreProcessFailed等事件但未编写处理逻辑,无法捕获初始化、导航阶段的错误信息。

修复后的完整代码实现

自定义渲染器代码

using Microsoft.Maui.Controls.Handlers.Compatibility;
using Microsoft.UI.Xaml.Controls;
using Microsoft.Web.WebView2.Core;
using WebView = Microsoft.Maui.Controls.WebView;
using WWebView = Microsoft.UI.Xaml.Controls.WebView2;

public class WindowsWebViewRenderer : ViewRenderer<WebView, WWebView>
{
    private WWebView _webView;

    protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
    {
        base.OnElementChanged(e);

        if (Control == null)
        {
            _webView = new WebView2();
            Connect(_webView);
            // 监听核心组件初始化完成事件
            _webView.CoreWebView2InitializationCompleted += OnCoreWebView2InitializationCompleted;
            SetNativeControl(_webView);
        }

        if (e.OldElement != null)
        {
            // 清理旧元素的事件绑定
            _webView.CoreWebView2InitializationCompleted -= OnCoreWebView2InitializationCompleted;
            Disconnect(_webView);
        }
    }

    private void Connect(WWebView webView)
    {
        if (webView == null) return;
        webView.CoreProcessFailed += OnCoreProcessFailed;
        webView.NavigationStarting += OnNavigationStarting;
        webView.NavigationCompleted += OnNavigationCompleted;
    }

    private void Disconnect(WWebView webView)
    {
        if (webView == null) return;
        webView.CoreProcessFailed -= OnCoreProcessFailed;
        webView.NavigationStarting -= OnNavigationStarting;
        webView.NavigationCompleted -= OnNavigationCompleted;
    }

    private async void OnCoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
    {
        if (e.IsSuccess)
        {
            await LoadContentAsync();
        }
        else
        {
            Console.WriteLine($"CoreWebView2初始化失败: {e.InitializationException.Message}");
        }
    }

    private async Task LoadContentAsync()
    {
        try
        {
            // 加载外部URL示例
            _webView.Source = new Uri("https://www.google.lk");

            // 加载本地HTML文件示例(取消注释使用)
            /*using var stream = await FileSystem.OpenAppPackageFileAsync("HTMLPage.html");
            using var reader = new StreamReader(stream);
            var htmlContent = reader.ReadToEnd();
            _webView.CoreWebView2.NavigateToString(htmlContent);*/
        }
        catch (Exception ex)
        {
            Console.WriteLine($"加载内容出错: {ex.Message}\n{ex.StackTrace}");
        }
    }

    // 实现事件处理以捕获错误
    private void OnCoreProcessFailed(object sender, CoreWebView2ProcessFailedEventArgs e)
    {
        Console.WriteLine($"WebView2核心进程失败: {e.Reason} - {e.ProcessFailedDetails?.Description}");
    }

    private void OnNavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e)
    {
        Console.WriteLine($"开始导航到: {e.Uri}");
    }

    private void OnNavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
    {
        if (e.IsSuccess)
        {
            Console.WriteLine($"导航完成: {e.Uri}");
        }
        else
        {
            Console.WriteLine($"导航失败: {e.WebErrorStatus}");
        }
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing && _webView != null)
        {
            Disconnect(_webView);
            _webView.Dispose();
        }
        base.Dispose(disposing);
    }
}

关键修复点说明

  • 等待核心组件初始化:通过CoreWebView2InitializationCompleted事件确保WebView2核心组件就绪后再加载内容,避免静默失败。
  • 规范异步操作:将内容加载改为async Task方法,保证异步逻辑执行完整。
  • 补充错误捕获逻辑:实现所有注册的事件处理方法,便于定位初始化、导航、进程崩溃等阶段的问题。
  • 资源清理:添加Dispose方法和旧元素事件解绑逻辑,避免内存泄漏。

本地HTML文件加载注意事项

若加载本地HTML文件,需确保:

  • 将HTMLPage.html的生成操作设置为嵌入的资源或内容,并确认文件已包含在输出包内。
  • 使用FileSystem.OpenAppPackageFileAsync时,路径需与文件实际位置一致(根目录直接写文件名即可)。

内容的提问来源于stack exchange,提问作者D.madushanka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 13:43:16