从嵌入式Cefsharp浏览器调用WinForm过程

时间:2018-03-16 11:02:34

标签: javascript winforms chromium cefsharp

我正在创建一个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

提前谢谢!

1 个答案:

答案 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