WinForms - Как выполнить код приложения C # изнутри элемента управления WebBrowser? - PullRequest
4 голосов
/ 20 ноября 2008

У меня есть форма, содержащая элемент управления веб-браузера. Этот элемент управления браузера загрузит HTML-код с диска и отобразит его. Я хочу иметь возможность иметь кнопку в коде доступа C # HTML в моей форме.

Например, кнопка в HTML может вызвать метод Close () в форме.

Целевая платформа: C # и Windows Forms (любая версия)

Ответы [ 6 ]

18 голосов
/ 04 декабря 2008

Я реализовал это в нескольких приложениях в прошлом, вот как: (Примечание: приведенный ниже пример не готов к работе и должен использоваться только в качестве руководства).

Сначала создайте обычный класс .NET (public), который содержит публичные методы, которые вы хотите вызывать из Javasvcipt, запущенного в вашем элементе управления веб-браузера.

Самое главное, он должен быть украшен атрибутом ComVisible (true)] из пространства имен System.Runtime.InteropServices (Javascript в IE основан на 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);  
    }
}

Затем в форме .NET, содержащей ваш элемент управления веб-браузера, создайте экземпляр класса COMVisible, затем установите для элемента управления веб-браузера ObjectForScripting этот экземпляр:

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

         browserControl.ObjectForScripting = m_external; 
    }

Наконец, в вашем Javascript, запущенном в элементе управления веб-браузера, вы получаете доступ к методам .NET через объект window.external. В этом случае window.external фактически ссылается (косвенно через оболочку взаимодействия COM) на созданный выше «внешний» объект:

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

Имейте в виду, что вызовы из Javascript в .NET проходят через уровень взаимодействия COM, и поэтому должен выполняться запрос интерфейса по умолчанию, сортировка параметров и т. Д. Другими словами, это может быть относительно МЕДЛЕННО, поэтому проведите некоторое тестирование производительности, если вы планируете сделать несколько вызовов, например, из цикла.

Кроме того, просто для дальнейшего использования вызов кода Javascript из .NET проще, просто используйте метод Document.InvokeScript:

    browserControl.Document.InvokeScript("jScriptFunction", new object[] { "param1", 2, "param2" });
9 голосов
/ 20 ноября 2008

Посмотрите на свойство WebBrowser.ObjectForScripting . Удалось заставить Google Карты общаться с приложением Windows Form, используя это.

2 голосов
/ 20 ноября 2008

Что я делал в VB6:

0 голосов
/ 07 марта 2012

Я делал это несколько лет назад и писал об этом здесь:

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

В частности, вы можете использовать Type.InvokeMember() для вызова JavaScript из C #.

0 голосов
/ 20 ноября 2008

Все, что вам нужно сделать, это добавить обработчик события Navigating для WebBrowser.

Это событие вызывается до перехода браузера на следующую страницу. Это позволяет вам прерывать процесс и делать все, что вы захотите, включая отмену навигации и вызов вашего кода.

Довольно прост в использовании. Единственное предостережение, с которым я столкнулся, это то, что вы не можете просматривать PostData - посмотрите мой вопрос здесь: PostData Question

Вот пример кода:

    private void MyMethod()
    {
        // do something
    }

    private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
    {
        MyMethod();
        e.Cancel = true;
    }
0 голосов
/ 20 ноября 2008

Это возможно, но я не сделал этого в .NET. Несколько лет назад у меня было приложение C ++, в котором размещался элемент управления веб-браузера (ActiveX). Из HTML в элементе управления можно было вызывать элемент управления ActiveX и заставлять его что-то делать.

То же самое должно быть возможно в .NET, хотя HTML DOM / JavaScript не будет знать о C #. Но если вы поместите свою функциональность .NET в COM-объект, вы сможете вызывать методы для объектов COM / ActiveX, которые в свою очередь будут вызывать ваш код C #.

Надеюсь, это поможет.

...