如何在CefSharp嵌入式浏览器中从JS调用WinForm的VB方法?
解决CefSharp中JS调用WinForm VB方法的问题
我懂你现在的困扰——在原生IE浏览器里用window.external就能轻松调用WinForm方法,但切换到CefSharp后这套机制就失效了。别担心,CefSharp有专门的.NET-JS交互方案,针对你使用的3.3239版本,下面是一步步的实现方案:
1. 定义JS桥接类
首先我们需要一个中间类来做JS和WinForm的桥梁,这个类要标记为ComVisible,让CefSharp能识别它:
Imports System.Runtime.InteropServices <ComVisible(True)> Public Class JsToWinFormBridge Private ReadOnly _hostForm As Form1 ' 构造函数传入主窗体实例 Public Sub New(hostForm As Form1) _hostForm = hostForm End Sub ' 暴露给JS调用的方法,这里直接调用主窗体的HelloWorld Public Sub HelloWorld() _hostForm.HelloWorld() End Sub End Class
2. 在WinForm中注册桥接对象
接下来在Form1的初始化代码里,把这个桥接类实例注册到CefSharp浏览器中,这样JS就能访问到它了:
修改你的Form1代码:
Imports CefSharp.WinForms Imports CefSharp Public Class Form1 Private WithEvents browser As ChromiumWebBrowser Private _jsBridge As JsToWinFormBridge Public Sub New() InitializeComponent() Dim settings As New CefSettings() Cef.Initialize(settings) browser = New ChromiumWebBrowser("http://localhost") With { .Dock = DockStyle.Fill } panBrowser.Controls.Add(browser) ' 初始化桥接对象并注册到浏览器,命名为winformApi供JS调用 _jsBridge = New JsToWinFormBridge(Me) browser.RegisterJsObject("winformApi", _jsBridge, False) End Sub ' 你的原有方法,改成Public让桥接类能调用 Public Sub HelloWorld() MsgBox("Hello World") End Sub End Class
这里
RegisterJsObject的第三个参数False表示同步调用,如果你的方法涉及耗时操作,可以改成True用异步方式调用。
3. 在JS中调用WinForm方法
现在你可以在JS里通过我们注册的winformApi对象来触发WinForm的方法了:
<script> function onClick(e) { // 替换原来的window.external,调用我们注册的桥接对象方法 winformApi.HelloWorld(); }; </script>
额外提示
- 如果你需要传递参数,直接在桥接类的方法里添加参数即可,比如:
对应的JS调用:Public Sub ShowCustomMessage(message As String) MsgBox($"Received from JS: {message}") End SubwinformApi.ShowCustomMessage("Hi from Leaflet map!"); - 确保桥接类的方法是Public的,并且类必须标记
<ComVisible(True)>,否则CefSharp无法识别这些方法。 - 如果你后续升级CefSharp版本,
RegisterJsObject可能会被标记为过时,届时可以改用RegisterAsyncJsObject,用法基本一致。
内容的提问来源于stack exchange,提问作者Ivaylo
相关产品推荐
相关产品推荐

