4

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

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

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

4

6 回答 6

18

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

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

最重要的是,它必须使用 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);  
    }
}

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

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

         browserControl.ObjectForScripting = m_external; 
    }

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

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

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

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

    browserControl.Document.InvokeScript("jScriptFunction", new object[] { "param1", 2, "param2" });
于 2008-12-04T06:24:23.597 回答
9

查看WebBrowser.ObjectForScripting属性。设法让谷歌地图使用它与 Windows 窗体应用程序对话。

于 2008-11-20T16:43:25.147 回答
2

我在 VB6 中做了什么:

  • 在 HTML 文档中添加一堆自定义 < A > 标签,将它们的 href 设置为对您有意义的东西,例如 '#closeform'
  • 在 BeforeNavigate 方法中,检查浏览器尝试访问的地址并采取相应措施。然后取消浏览器导航。
于 2008-11-20T16:42:24.743 回答
0

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

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

希望这可以帮助。

于 2008-11-20T16:34:08.130 回答
0

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

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

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

这是一些示例代码:

    private void MyMethod()
    {
        // do something
    }

    private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
    {
        MyMethod();
        e.Cancel = true;
    }
于 2008-11-20T16:41:43.700 回答
0

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

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

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

于 2012-03-06T21:11:26.010 回答