WinForms - 如何从 WebBrowser 控件内部执行 C# 应用程序代码?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/305915/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 22:29:06  来源:igfitidea点击:

WinForms - How do I execute C# application code from inside WebBrowser control?

c#winformswebbrowser-control

提问by Brian Lyttle

I have a form containing a web browser control. This browser control will load some HTML from disk and display it. I want to be able to have a button in the HTML access C# code in my form.

我有一个包含 Web 浏览器控件的表单。这个浏览器控件将从磁盘加载一些 HTML 并显示它。我希望能够在我的表单中的 HTML 访问 C# 代码中有一个按钮。

For example, a button in the HTML might call the Close() method on the form.

例如,HTML 中的按钮可能会调用表单上的 Close() 方法。

Target platform: C# and Windows Forms (any version)

目标平台:C# 和 Windows 窗体(任何版本)

采纳答案by k?e?m?p? ?

Look at the WebBrowser.ObjectForScriptingproperty. Managed to get Google Maps talking to a windows forms application using this.

查看WebBrowser.ObjectForScripting属性。设法让谷歌地图使用这个与 Windows 窗体应用程序交谈。

回答by Steve Dunn

This is possible, but I haven't done it in .NET. A few years back I had a C++ application that hosted a web browser control (ActiveX). From the HTML in the control, it was possible to call 'out' to the ActiveX control and get it to do things.

这是可能的,但我没有在 .NET 中做过。几年前,我有一个托管 Web 浏览器控件 (ActiveX) 的 C++ 应用程序。从控件中的 HTML 中,可以调用 ActiveX 控件并让它执行操作。

The same should be possible in .NET, although HTML DOM/JavaScript won't know about C#. But if you wrap your .NET functionality in a COM object, you should be able to call methods on the COM/ActiveX objects which will in-turn call your C# code.

在 .NET 中应该也是如此,尽管 HTML DOM/JavaScript 不知道 C#。但是,如果您将 .NET 功能包装在 COM 对象中,您应该能够调用 COM/ActiveX 对象上的方法,这些方法将依次调用您的 C# 代码。

Hope this helps.

希望这可以帮助。

回答by Steve Dunn

All you have to do is add an event handler for the WebBrowser's Navigating event.

您所要做的就是为 WebBrowser 的 Navigating 事件添加一个事件处理程序。

This event gets fired before the browser navigates to the next page. It allows you to interrupt the process and do whatever you want, including cancelling the navigation and calling into your code.

在浏览器导航到下一页之前触发此事件。它允许您中断流程并做任何您想做的事情,包括取消导航和调用您的代码。

Pretty easy to use. The only caveat I've come across is that you can't view the PostData -- see my question here: PostData Question

很容易使用。我遇到的唯一警告是您无法查看 PostData - 请在此处查看我的问题: PostData Question

Here's some sample code:

这是一些示例代码:

    private void MyMethod()
    {
        // do something
    }

    private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
    {
        MyMethod();
        e.Cancel = true;
    }

回答by Loris

What I did in VB6:

我在 VB6 中做了什么:

  • Add a bunch of custom < A > tags in the HTML document, set their href to something meaningful to you, like '#closeform'
  • On the BeforeNavigate method, check the address the browser is trying to go to and act accordingly. Then cancel the browser navigation.
  • 在 HTML 文档中添加一堆自定义 < A > 标签,将它们的 href 设置为对您有意义的内容,例如 '#closeform'
  • 在 BeforeNavigate 方法中,检查浏览器试图访问的地址并采取相应措施。然后取消浏览器导航。

回答by Ash

I've implemeted this in a few applications in the past, here's how: (NB: the example below is not production ready and should be used as a guide only).

过去我已经在一些应用程序中实现了这一点,方法如下:(注意:下面的示例尚未准备好用于生产,应仅用作指南)。

First create a normal .NET class (public) that contains public methods that you wish to call from Javasvcipt running in your web browser control.

首先创建一个普通的 .NET 类(公共),其中包含您希望从 Web 浏览器控件中运行的 Javasvcipt 调用的公共方法。

Most importantly it must be decorated with the ComVisible(true)] attribute from the System.Runtime.InteropServices namespace (Javascript in IE is COM based). It can be called anything, I've called it "External" to make things clearer.

最重要的是,它必须使用 System.Runtime.InteropServices 命名空间中的 ComVisible(true)] 属性进行修饰(IE 中的 Javascript 是基于 COM 的)。它可以被称为任何东西,为了让事情更清楚,我称之为“外部”。

using System.Runtime.InteropServices;

[ComVisible(true)]
public class External
{
    private static MainWindow m_mainWindow = null;

    public External(MainWindow mainWindow)
    {
        m_mainWindow = mainWindow; 
    }

    public void CloseApplication()
    {
        m_mainWindow.Close();
    }


    public string CurrentDate(string format)
    {
        return DateTime.Now.ToString(format);  
    }
}

Next in the .NET form containing your web browser control create an instance of the COMVisible class, then set the web browser controls ObjectForScripting to that instance:

接下来在包含 Web 浏览器控件的 .NET 表单中创建 COMVisible 类的实例,然后将 Web 浏览器控件 ObjectForScripting 设置为该实例:

    private void MainWindow_Load(object sender, EventArgs e)
    {
         m_external = new External(this);

         browserControl.ObjectForScripting = m_external; 
    }

Finally, in your Javascript running in the web browser control, you access the .NET methods via the window.external object. In this case window.external actually references (indirectly via a COM interop wrapper) the "External" object created above:

最后,在 Web 浏览器控件中运行的 Javascript 中,您可以通过 window.external 对象访问 .NET 方法。在这种情况下 window.external 实际上引用(间接通过 COM 互操作包装器)上面创建的“外部”对象:

// Javascript code
function CloseButton_Click()
{
    if (window.external)
    {
        window.external.CloseApplication();
    }
}

Be aware that calls from Javascript to .NET pass through the COM interop layer and so querying of the default interface, marshalling of parameters etc must occur. In other words it can be relatively SLOW, so do some performance testing if you plan to make multiple calls for example from within a loop.

请注意,从 Javascript 到 .NET 的调用会通过 COM 互操作层,因此必须进行默认接口的查询、参数的编组等。换句话说,它可能相对较慢,因此如果您计划在循环中进行多次调用,请进行一些性能测试。

Also, just for future reference, calling Javascript code from .NET is simpler, just use the Document.InvokeScript method:

另外,仅供参考,从 .NET 调用 Javascript 代码更简单,只需使用 Document.InvokeScript 方法:

    browserControl.Document.InvokeScript("jScriptFunction", new object[] { "param1", 2, "param2" });

回答by Matthew Skelton

I did this several years ago, and blogged about it here:

几年前我这样做了,并在这里写了博客:

http://matthewskelton.wordpress.com/2007/04/21/calling-javascript-from-c/

http://matthewskelton.wordpress.com/2007/04/21/calling-javascript-from-c/

Specifically, you can use Type.InvokeMember()to call JavaScript from C#.

具体来说,您可以使用Type.InvokeMember()从 C# 调用 JavaScript。