Взаимодействие C# и JavaScript

153

В примерах из предыдущей статьи приложение Silverlight обращалось к браузеру для манипулирования элементами HTML. Один из недостатков этого способа состоит в том, что код приложения жестко привязан к странице HTML. При его создании необходимо заложить в код информацию об элементах текущей страницы и уникальных значениях id. Как результат, после изменения HTML-страницы код Silverlight становится неработоспособным.

Для решения этой проблемы необходимо запрограммировать взаимодействие кодов, а не элементов. Например, приложение Silverlight может обновлять HTML-содержимое, вызывая методы JavaScript, определенные на странице. Код JavaScript создает дополнительную прослойку между Silverlight и HTML, обеспечивая гибкость приложения.

При использовании этого способа устраняется необходимость перекомпиляции приложения Silverlight, потому что элементы HTML можно изменять, обновляя методы JavaScript для учета изменений. Взаимодействие может выполняться и в обратном направлении. Например, можно создать код JavaScript, который вызывает методы Silverlight, написанные на C#. В следующих разделах подробно рассматриваются оба подхода.

Вызов сценария JavaScript из кода Silverlight

С помощью классов Silverlight, приведенных в пространстве имен System.Windows.Browser, можно вызывать функции JavaScript, объявленные в блоке сценариев. Этот способ взаимодействия позволяет коду Silverlight взаимодействовать с HTML-страницей. Он особенно полезен, если уже существует страница с полным набором функций JavaScript. Вместо дублирования кодов, манипулирующих элементами страницы, можно вызывать существующие функции.

Рассмотрим функцию changeParagraph, определенную в разделе <head> HTML-страницы:

function changeParagraph(newText) {
     var element = document.getElementById("paragraph").innerHTML(newText);
}

Для ее вызова в Silverlight нужно применить метод HtmlPage.Window.GetProperty () и передать ему имя функции. Метод возвратит объект типа ScriptObject, через который можно в любой момент запустить функцию, вызвав метод InvokeSelf():

ScriptObject script = 
        (ScriptObject)HtmlPage.Window.GetProperty("changeParagraph");

script.InvokeSelf("Новый текст абзаца");

Вызов методов Silverlight из браузера

Код JavaScript может вызывать методы Silverlight, написанные на C#. Эта задача немного сложнее. Для ее решения необходимо выполнить ряд действий:

  1. Создайте в коде Silverlight открытый метод, предоставляющий информацию или средства, которые нужно использовать на HTML-странице. Метод можно поместить в классе страницы или в отдельном классе. Используйте простые типы данных, такие как строки, булевы значения и числа, в противном случае вам придется сериализовать объекты данных для совместимости с типами JavaScript.

  2. Добавьте атрибут ScriptableMember в объявление метода, который планируете вызывать из JavaScript.

  3. Добавьте атрибут ScriptableType в объявление класса, содержащего метод.

  4. Чтобы предоставить сценарию доступ к методу Silverlight, вызовите метод HtmlPage.RegisterScriptableObject().

После выполнения этих операций код JavaScript сможет вызывать методы Silverlight посредством элемента <object>, представляющего область содержимого Silverlight. Программа Visual Studio по умолчанию создает тестовую страницу и присваивает имя silverlightControlHost элементу <div>, из которого мы и будем получать элемент object.

В приведенном ниже примере используется пользовательский класс страницы. Он содержит метод, доступный в сценариях и регистрируемый при первом создании страницы:

[ScriptableType()]
public partial class MainPage : UserControl
{
        public MainPage()
        {
            InitializeComponent();
            HtmlPage.RegisterScriptableObject("Page", this);
        }

        [ScriptableMember()]
        public void ChangeText(string newText)
        {
            txt_block.Text = newText;
        }
}

При регистрации типа, доступного в сценариях, нужно задать имя объекта JavaScript и передать ссылку на объект. В данном примере экземпляр класса MainPage зарегистрирован с именем Page. Регистрация вынуждает Silverlight создать свойство Page в элементе управления. Чтобы вызвать метод, код JavaScript должен получить элемент управления Silverlight, извлечь его содержимое и вызвать его метод Page.ChangeText():

function updateSilverlightText()
{
      var control = document.getElementById("silverlightControlHost").getElementsByTagName("object")[0];
      control.content.Page.ChangeText("Обновленный текстовый блок Silverlight");
}

Запустить функцию JavaScript можно в любой момент времени. Приведенный ниже код запускает ее при щелчке на абзаце:

<p id="paragraph" style="font-size:16px; text-align:center;"
        onclick="updateSilverlightText()">
        Щелкните здесь, чтобы изменить<br />текстовый блок Silverlight</p>
Взаимодействие JavaScript и Silverlight

Создание экземпляра объекта Silverlight в браузере

В предыдущем примере демонстрируется вызов метода Silverlight в коде JavaScript. Платформа Silverlight предоставляет еще одну возможность взаимодействия кодов — создание объекта Silverlight в коде JavaScript.

Как и ранее, начнем с создания типа и метода, доступных в сценариях. Ниже приведен класс Silverlight, генерирующий случайные числа:

[ScriptableType()]
public class RandomNumbers
{
        private Random random = new Random();

        [ScriptableMember()]
        public int GetRandomNumberInPage(int min, int max)
        {
            return random.Next(min, max);
        }
}

Как и в предыдущем примере, нужно зарегистрировать класс, чтобы он был доступен в коде JavaScript. Однако на этот раз вместо метода RegisterScriptableObject() применим метод RegisterCreateableType():

public MainPage()
{
      InitializeComponent();
      HtmlPage.RegisterScriptableObject("Page", this);
      HtmlPage.RegisterCreateableType("RandomNumbers", typeof(RandomNumbers));
}

Для создания экземпляра зарегистрированного типа нужно извлечь элемент управления Silverlight и вызвать его метод content.services.createObject(). Ниже приведена функция JavaScript, которая выводит случайные числа в диапазоне от 1 до 100 с помощью экземпляра класса RandomNumbers, определенного в Silverlight:

function getRandom()
{
            var control = document.getElementById("silverlightControlHost")
                .getElementsByTagName("object")[0];
            var random = control.content.services.createObject("RandomNumbers");
            alert ("Случайное число равно " + random.GetRandomNumberInPage(1,100));
}
Создание объекта Silverlight в коде JavaScript
Пройди тесты
Лучший чат для C# программистов