Взаимодействие C# и JavaScript
153Silverlight 5 --- Взаимодействие C# и JavaScript
В примерах из предыдущей статьи приложение 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#. Эта задача немного сложнее. Для ее решения необходимо выполнить ряд действий:
Создайте в коде Silverlight открытый метод, предоставляющий информацию или средства, которые нужно использовать на HTML-странице. Метод можно поместить в классе страницы или в отдельном классе. Используйте простые типы данных, такие как строки, булевы значения и числа, в противном случае вам придется сериализовать объекты данных для совместимости с типами JavaScript.
Добавьте атрибут ScriptableMember в объявление метода, который планируете вызывать из JavaScript.
Добавьте атрибут ScriptableType в объявление класса, содержащего метод.
Чтобы предоставить сценарию доступ к методу 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>
Создание экземпляра объекта 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));
}