我正在创建一个WinForm应用程序,它包含一个嵌入式浏览器,在Leaflet框架的帮助下显示OSM地图。在WinForm端有图表,必须根据OSM地图上用户选择的标记进行更新。只要我在Visual Studio中使用本机浏览器,浏览器和winform之间的交互就会运行良好。但是由于IE中大量标记的渲染效果不佳,我在Cefsharp的帮助下被迫切换到Chromium。
我使用的Cefsharp版本是3.3239.1723.g071d1c1。部署浏览器没有任何问题(TheChrisKent教程帮助很多 - link)。
我面临的主要问题是如何在Cefsharp / Chromium浏览器中从JS调用Winform程序。
在VS中使用本机浏览器控件时,这可以很容易地完成,但我想在Cefsharp中这种方法完全不同。我正在网上阅读文档和一些可用的问题,但我无法找到答案。可能我需要根据Docs向.NET公开.NET类。说实话,我无法理解如何做到这一点。最重要的是我使用的是Visual Basic。
任何帮助都将受到高度赞赏。下面我可以展示我需要的非常简化。 JavaScript onClick事件应该触发WinForms HelloWorld()过程的执行。
//JavaScript side
<script>
function onClick(e) {
//How to Call Winform sub HelloWorld?
//with native browser this is done with "window.external.HelloWorld();"
};
WinForm如下所示:
Imports CefSharp.WinForms
Imports CefSharp
Public Class Form1
Private WithEvents browser As ChromiumWebBrowser
Public Sub New()
InitializeComponent()
Dim settings As New CefSettings()
CefSharp.Cef.Initialize(settings)
browser = New ChromiumWebBrowser("http://localhost") With {
.Dock = DockStyle.Fill
}
panBrowser.Controls.Add(browser)
End Sub
Private Sub HelloWorld()
MsgBox("Hello World")
End Sub
End Class
提前谢谢!
答案 0 :(得分:0)
在amaitland在评论中指出我在最新版本的Cefsharp中有一种新的绑定方法后,我做了一些额外的研究并找到了解决我问题的方法。下面是从嵌入式Cefsharp浏览器中运行的JavaScript调用VB过程“showMessage”的代码。此过程将写入从JS传递到Winform中的TextBox的字符串值。希望这对某人有所帮助。
JavaScript方面
function onClick(e) {
var popup = e.target.getPopup();
var content = popup.getContent();
// calling starts here
(async function() {
await CefSharp.BindObjectAsync("boundAsync", "bound");
// "showMessage" is the VB procedure to call in a class "boundAsync"
boundAsync.showMessage(content);
})();
// calling ends here
};
VB端
Imports CefSharp.WinForms
Imports CefSharp
Public Class Form1
Private WithEvents browser As ChromiumWebBrowser
// row below is needed for communication between the new class and Form1
Friend Shared MyInstance As Form1
Public Sub New()
InitializeComponent()
Dim settings As New CefSettings()
CefSharp.Cef.Initialize(settings)
browser = New ChromiumWebBrowser("localhost") With {
.Dock = DockStyle.Fill
}
panBrowser.Controls.Add(browser)
// add this line for registering a new class boundAsync
browser.JavascriptObjectRepository.Register("boundAsync", New BoundObject(), True)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
// row below is needed for communication between the new class and Form1
MyInstance = Me
End Sub
End Class
// declare the new class
Public Class BoundObject
// declare the procedure called by JS
// in this example a value passed from JS is assigned to a TextBox1 on Form1
Public Sub showMessage(ByVal msg As String)
If (Form1.MyInstance IsNot Nothing) AndAlso Not Form1.MyInstance.IsDisposed Then
If Form1.MyInstance.TextBox1.InvokeRequired Then
Form1.MyInstance.TextBox1.Invoke(New Action(Of String)(AddressOf showMessage), msg)
Else
Form1.MyInstance.TextBox1.Text = msg
End If
End If
End Sub
End Class