Xamarin.macOS自定义CustomWebView的Navigated事件未触发如何解决
解决方案
问题根因
你当前使用了默认的空WKNavigationDelegate实例,该实例没有实现WKWebView的导航回调方法,也没有将原生导航事件映射到自定义CustomWebView的Navigated事件上,所以事件无法触发,同时代码中存在重复赋值NavigationDelegate的无效逻辑。
实现代码
第一步:自定义WKNavigationDelegate子类
该子类负责接收原生WKWebView的导航回调,并映射到CustomWebView的对应事件:
public class CustomWebViewNavigationDelegate : WKNavigationDelegate { private readonly CustomWebView _customWebView; public CustomWebViewNavigationDelegate(CustomWebView webView) { _customWebView = webView; } // 页面开始加载时触发,对应CustomWebView的Navigating事件 public override void DidStartProvisionalNavigation(WKWebView webView, WKNavigation navigation) { base.DidStartProvisionalNavigation(webView, navigation); var args = new WebNavigatingEventArgs(WebNavigationEvent.NewPage, new UrlWebViewSource { Url = webView.Url?.AbsoluteString }, webView.Url?.AbsoluteString); _customWebView.SendNavigating(args); } // 页面加载完成时触发,对应CustomWebView的Navigated事件 public override void DidFinishNavigation(WKWebView webView, WKNavigation navigation) { base.DidFinishNavigation(webView, navigation); var args = new WebNavigatedEventArgs(WebNavigationEvent.NewPage, new UrlWebViewSource { Url = webView.Url?.AbsoluteString }, webView.Url?.AbsoluteString, WebNavigationResult.Success); _customWebView.SendNavigated(args); } // 页面加载失败时触发 public override void DidFailNavigation(WKWebView webView, WKNavigation navigation, NSError error) { base.DidFailNavigation(webView, navigation, error); var args = new WebNavigatedEventArgs(WebNavigationEvent.NewPage, new UrlWebViewSource { Url = webView.Url?.AbsoluteString }, webView.Url?.AbsoluteString, WebNavigationResult.Failure); _customWebView.SendNavigated(args); } // provisional阶段导航失败时触发 public override void DidFailProvisionalNavigation(WKWebView webView, WKNavigation navigation, NSError error) { base.DidFailProvisionalNavigation(webView, navigation, error); var args = new WebNavigatedEventArgs(WebNavigationEvent.NewPage, new UrlWebViewSource { Url = webView.Url?.AbsoluteString }, webView.Url?.AbsoluteString, WebNavigationResult.Failure); _customWebView.SendNavigated(args); } }
第二步:修改CustomWebView类
在你的CustomWebView类中添加方法,暴露内部的事件触发逻辑:
public class CustomWebView : WebView { // 保留你原来的CustomUserAgent等自定义属性 public void SendNavigating(WebNavigatingEventArgs args) { OnNavigating(args); } public void SendNavigated(WebNavigatedEventArgs args) { OnNavigated(args); } }
第三步:修改自定义Renderer代码
替换原来的空WKNavigationDelegate,删掉重复赋值逻辑:
[assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))] namespace DesktopClient.MacOS.CustomRenderers { public class CustomWebViewRenderer : ViewRenderer<CustomWebView, WKWebView> { private WKWebView wkWebView; protected override void OnElementChanged(ElementChangedEventArgs<CustomWebView> e) { base.OnElementChanged(e); if (Control == null) { WKWebViewConfiguration config = new WKWebViewConfiguration(); wkWebView = new WKWebView(Frame, config) { // 使用自定义的NavigationDelegate NavigationDelegate = new CustomWebViewNavigationDelegate(e.NewElement) }; SetNativeControl(wkWebView); WKWebViewContainer.WKWebView = wkWebView; } if (e.NewElement != null) { if (e.NewElement.Source is UrlWebViewSource source && !string.IsNullOrEmpty(source.Url)) { Control.LoadRequest(new NSUrlRequest(new NSUrl(source.Url))); } Control.CustomUserAgent = e.NewElement.UserAgent; } } } }
注意事项
- 如果需要处理跨域请求、权限申请、跳转拦截等逻辑,可在
CustomWebViewNavigationDelegate中重写对应的WKNavigationDelegate方法实现。 - 如出现内存泄漏问题,可将Delegate中的
_customWebView改为弱引用持有。 - 若使用MAUI框架,更推荐使用Handler替代自定义Renderer实现,逻辑与上述映射思路一致。
内容的提问来源于stack exchange,提问作者Max951
相关产品推荐
相关产品推荐

