.NET MAUI UWP中WebView2的DOMContentLoaded为空及本地文件加载问题
Xamarin Forms UWP迁移MAUI:WebView2本地HTML加载问题
问题1:Control.CoreWebView2.DOMContentLoaded始终为空,且无ScriptReceived事件
问题说明
在自定义FormsWebViewRenderer的SetupControl方法中,直接访问Control.CoreWebView2会发现其为空,同时WebView2不存在原Xamarin中的ScriptReceived事件。
原问题代码
void SetupControl() { var control = new WebView2(); _resolver = new LocalFileStreamResolver(this); SetNativeControl(control); FormsWebView.CallbackAdded += OnCallbackAdded; Control.NavigationStarting += OnNavigationStarting; Control.NavigationCompleted += OnNavigationCompleted; // 此处CoreWebView2为空,无法绑定事件 Control.CoreWebView2.DOMContentLoaded += OnDOMContentLoaded; // MAUI中无此事件 //Control.CoreWebView2.ScriptReceived += OnScriptReceived; SetNativeControl(control); OnControlChanged?.Invoke(this, control); }
解决方法
MAUI中的WebView2控件需要先完成CoreWebView2的初始化才能访问其成员,可通过EnsureCoreWebView2Async方法异步初始化;同时原ScriptReceived事件需替换为WebMessageReceived事件:
async void SetupControl() { var control = new WebView2(); _resolver = new LocalFileStreamResolver(this); SetNativeControl(control); // 异步初始化CoreWebView2 await control.EnsureCoreWebView2Async(); FormsWebView.CallbackAdded += OnCallbackAdded; Control.NavigationStarting += OnNavigationStarting; Control.NavigationCompleted += OnNavigationCompleted; // 初始化完成后即可绑定DOMContentLoaded事件 Control.CoreWebView2.DOMContentLoaded += OnDOMContentLoaded; // 替换原ScriptReceived事件为WebMessageReceived Control.CoreWebView2.WebMessageReceived += OnWebMessageReceived; OnControlChanged?.Invoke(this, control); } // 替换原OnScriptReceived的实现 private void OnWebMessageReceived(CoreWebView2 sender, CoreWebView2WebMessageReceivedEventArgs args) { // 处理脚本发送的消息,args.WebMessageAsJson可获取消息内容 var message = args.WebMessageAsJson; // 原逻辑迁移到此处 }
问题2:MAUI中缺失BuildLocalStreamUri和NavigateToLocalStreamUri方法,无法加载本地文件
问题说明
原Xamarin中通过BuildLocalStreamUri和NavigateToLocalStreamUri结合IUriToStreamResolver加载本地HTML的方式,在MAUI中无法直接使用,因为WebView2的API已调整。
原问题代码
void LoadLocalFile(string source) { var src = Control.BuildLocalStreamUri("/", source); Control.NavigateToLocalStreamUri(src, _resolver); }
解决方法
MAUI中可使用CoreWebView2.SetVirtualHostNameToFolderMapping方法,将虚拟主机名映射到本地文件目录,直接通过HTTP协议访问本地文件,替代原流解析方式:
async void LoadLocalFile(string source) { // 确保CoreWebView2已初始化 await Control.EnsureCoreWebView2Async(); // 获取本地文件所在的文件夹路径(示例:项目Assets中的www文件夹) string localFolderPath = Path.Combine(AppContext.BaseDirectory, "www"); // 设置虚拟主机映射,将https://app.local映射到本地文件夹 Control.CoreWebView2.SetVirtualHostNameToFolderMapping( "app.local", localFolderPath, CoreWebView2HostResourceAccessKind.Allow); // 构造访问URL,加载指定文件 string url = $"https://app.local/{source}"; Control.Source = new Uri(url); }
关于原LocalFileStreamResolver的说明
使用虚拟主机映射后,无需再维护IUriToStreamResolver实现,WebView2会自动处理本地文件的加载,简化了本地资源访问逻辑。如果仍需自定义资源解析,可通过CoreWebView2.AddWebResourceRequestedFilter结合WebResourceRequested事件实现。
内容的提问来源于stack exchange,提问作者D.madushanka
相关产品推荐
相关产品推荐

