Windows Forms中使用WebView2如何获取鼠标点击的页面元素
WebView2 获取指定坐标对应DOM元素的解决方案
WebView2 没有提供和旧版WebBrowser控件对等的托管端GetElementFromPointAPI,要实现该需求需要通过托管代码与页面JS互操作的方式实现,具体实现如下:
实现思路
利用WebView2的JS注入能力,在页面中监听右键点击事件/主动执行JS查询坐标对应元素,将元素属性序列化后回传给WinForm宿主程序,再绑定到数据网格控件即可。
具体实现步骤
1. 被动监听右键点击获取元素(推荐,匹配原有业务场景)
无需自己处理坐标转换,JS端直接可以拿到右键点击的目标元素:
- 首先确保WebView2完成初始化,注入全局JS监听右键事件
- 注册消息接收事件,处理JS回传的元素属性数据
代码示例
using System.Text.Json; using Microsoft.Web.WebView2.WinForms; // 窗体加载时初始化WebView2 private async void MainForm_Load(object sender, EventArgs e) { // 等待WebView2核心初始化完成 await webView21.EnsureCoreWebView2Async(); // 注入JS脚本,所有页面加载时都会自动执行该脚本 await webView21.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(@" // 监听全局右键点击事件 document.addEventListener('contextmenu', (event) => { // 不需要屏蔽默认右键菜单可以删除下一行 event.preventDefault(); const targetEl = event.target; // 自定义收集需要的元素属性 const elData = { tagName: targetEl.tagName, id: targetEl.id, class: targetEl.className, text: targetEl.innerText?.slice(0, 200) ?? '' }; // 向托管端发送消息 window.chrome.webview.postMessage(elData); }); "); // 监听JS端发送的消息 webView21.CoreWebView2.WebMessageReceived += (s, args) => { // 反序列化JS回传的JSON数据 JsonElement elInfo = JsonSerializer.Deserialize<JsonElement>(args.WebMessageAsJson); // 将数据添加到DataGridView dataGridView1.Rows.Add( elInfo.GetProperty("tagName").GetString(), elInfo.GetProperty("id").GetString(), elInfo.GetProperty("class").GetString(), elInfo.GetProperty("text").GetString() ); }; }
2. 主动传入坐标查询元素(可选)
如果需要在托管端主动传入客户端坐标查询对应元素,可以调用ExecuteScriptAsync执行JS内置的elementFromPoint方法:
/// <summary> /// 传入客户端坐标,获取对应DOM元素属性 /// </summary> /// <param name="x">客户端X坐标</param> /// <param name="y">客户端Y坐标</param> private async Task<JsonElement> GetElementFromPointAsync(int x, int y) { // 执行JS查询坐标对应元素,序列化需要的属性 string script = $@" const el = document.elementFromPoint({x}, {y}); JSON.stringify({{ tagName: el.tagName, id: el.id, class: el.className, text: el.innerText?.slice(0, 200) ?? '' }}); "; string jsonResult = await webView21.CoreWebView2.ExecuteScriptAsync(script); return JsonSerializer.Deserialize<JsonElement>(jsonResult); }
注意事项
- 可以根据业务需求自行在JS侧扩展需要收集的元素属性,无需修改通信逻辑
- 如果项目中已经引入Newtonsoft.Json,也可以用Newtonsoft的API反序列化JSON数据,写法更简单
- 主动查询坐标时注意坐标是相对于WebView2控件的客户端坐标,不需要额外做屏幕坐标转换
内容的提问来源于stack exchange,提问作者Vemula Dheeraj
相关产品推荐
相关产品推荐

