首页 文章

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

提问于
浏览
0

我正在创建一个WinForm应用程序,其中包含一个嵌入式浏览器,在Leaflet框架的帮助下显示OSM Map . 在WinForm端有图表,必须根据OSM Map 上用户选择的标记进行更新 . 只要我在Visual Studio中使用本机浏览器,浏览器和winform之间的交互就会运行良好 . 但由于IE中大量标记的渲染效果不佳,我在Cefsharp的帮助下被迫切换到Chromium .

Cefsharp版本,我使用的是3.3239.1723.g071d1c1 . 部署浏览器没有问题(TheChrisKent教程有很多帮助 - link) .

The main issue which I am facing is how to call a Winform procedure from JS within Cefsharp/Chromium browser.

在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

    在amaitland在评论中指出我在最新版本的Cefsharp中有一种新的绑定方法后,我做了一些额外的研究并找到了解决我的问题的方法 . 下面是从嵌入式Cefsharp浏览器中运行的JavaScript调用VB过程“showMessage”的代码 . 此过程将写入从JS传递到Winform中的TextBox的字符串值 . 希望这可能对某人有所帮助 .

    JavaScript side

    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 side

    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
    

相关问题