MAUI中如何高效实现WebView(JS/HTML)向C#传递数据?
优化MAUI WebView中JS向C#传递数据的方案
你当前的轮询方式会产生不必要的周期性性能开销,以下是两种更高效的事件驱动型方案,完全消除轮询带来的问题:
使用WebMessageReceived事件(跨平台推荐)
这是MAUI WebView原生支持的消息通信机制,JS在用户操作触发时主动发送数据,C#端监听事件接收,无需轮询。C#端代码:
public partial class MapPage : ContentPage { public MapPage() { InitializeComponent(); MyWebView.WebMessageReceived += OnWebMessageReceived; } private void OnWebMessageReceived(object sender, WebMessageReceivedEventArgs e) { // 解析JS传来的删除标记数据 var deletedMarker = JsonSerializer.Deserialize<MarkerModel>(e.WebMessageAsJson); // 执行删除逻辑 ProcessDeletedMarker(deletedMarker); } private void ProcessDeletedMarker(MarkerModel marker) { // 这里编写处理删除标记的业务代码 } } // 标记数据模型 public class MarkerModel { public string Id { get; set; } public double Lat { get; set; } public double Lng { get; set; } }JS端(Leaflet删除标记时触发):
// 绑定Leaflet标记的移除事件 marker.on('remove', function(e) { const markerData = { id: e.target.options.id, lat: e.target.getLatLng().lat, lng: e.target.getLatLng().lng }; // 向C#发送消息 window.chrome.webview.postMessage(markerData); });绑定C#对象到JS上下文
将C#对象直接暴露给JS,让JS可以直接调用C#方法传递数据,适合复杂交互场景。C#端代码:
// 定义供JS调用的交互类 public class MapJsInterop { private readonly MapPage _page; public MapJsInterop(MapPage page) { _page = page; } // 标记该方法允许JS调用 [JSInvokable] public void NotifyMarkerDeleted(string markerJson) { var marker = JsonSerializer.Deserialize<MarkerModel>(markerJson); _page.ProcessDeletedMarker(marker); } } // 在页面中绑定对象到JS public partial class MapPage : ContentPage { protected override void OnNavigatedTo(NavigatedToEventArgs e) { base.OnNavigatedTo(e); // 将C#对象注册到JS全局上下文,命名为MapInterop MyWebView.AddJavaScriptBinding(new MapJsInterop(this), "MapInterop"); } }JS端调用:
marker.on('remove', function(e) { const markerData = JSON.stringify({ id: e.target.options.id, lat: e.target.getLatLng().lat, lng: e.target.getLatLng().lng }); // 直接调用C#方法 MapInterop.NotifyMarkerDeleted(markerData); });
方案优势
两种方案均为事件驱动,仅在用户实际执行删除操作时才触发JS与C#的通信,彻底消除轮询带来的周期性性能消耗,同时数据传递更实时,避免了轮询间隔导致的延迟问题。
内容的提问来源于stack exchange,提问作者HarrySocks
相关产品推荐
相关产品推荐

