Flash from Silverlight
Возникла необходимость открыть Flash-элемент из Silverlight. Если у вас интерактивная презентация, игра на флеше либо приложение, которое паралельно разрабатывается вместе с Silverlight-приложением. Проблема в том, что есть случаи, когда просто конвертация swf2xaml - не есть решение. Либо из-за трудоемкости процесса, либо нехватки времени, либо технических проблем. А обычно весь букет в комплекте.
Сделаем один проект, где Silverlight-приложение встроено в html-страницу.
В файле Page.xaml выставим ширину и высоту UserControl Width="Auto" Height="Auto". Распишем небольшую условную структуру Grid – из двух колонок, одна из которых в 2 раза по ширине больше чем вторая.
<Grid x:Name="LayoutRoot" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
</Grid>
Поместим в Grid кнопку
<Button x:Name="ShowButton" Width="90" Height="90" Margin="10">
<Button.Content>
<TextBlock Text="Show Flash" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Button.Content>
</Button>
Скопируем и добавим теперь в наш проект любой swf-файл (в данном случае у меня galaxy.swf)
Добавим обработчик события на клик у кнопки в файле page.xaml.
<Button x:Name="ShowButton" Width="90" Height="90" Click="ShowButton_Click">
Теперь создадим в файле Default.html еще один слой, и расположим его после слоя
<div id="silverlightControlHost">
Код слоя в нашем случае отображает элемент Flash. C помощью style="display: none" скроем его, так как при первоначальной загрузке приложения нам не нужно отображать его.
<div id="flashControlHost" style="display: none">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0"
width="65%" height="65%">
<param name="movie" value="galaxy.swf" />
<param name="quality" value="high" />
<embed src="galaxy.swf" quality="high" pluginspage="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash"
type="application/x-shockwave-flash" width="65%" height="65%"></embed>
</object>
</div>
Теперь напишем немного кода на JavaScript.
Наша цель – возможность подменять данную флешку, задавая три параметра – путь к файлу, ширину и высоту (желательно в процентах – с учетом изменения размеров экрана).
И так –выше, в коде файла Default.html , после функции onSilverlightError допишем еще одну функцию, которая будет принимать три параметра, отображать слой поверх нашего слоя с Silverlight-приложением (за счет zIndex ) .
function ShowSWF(swfPath, w, h) {
var flashDiv = document.getElementById("flashControlHost");
flashDiv.style.display = 'block';
flashDiv.style.zIndex = 1000;
flashDiv.style.position = 'absolute';
flashDiv.style.top = 0;
flashDiv.style.left = 0;
flashDiv.style.width = w + '%';
flashDiv.style.height = h + '%';
var flashStr = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0" width="100%" height="100%">';
flashStr += '<param name="movie" value="' + swfPath + '" />';
flashStr += '<param name="quality" value="high" />';
flashStr += '<embed src="' + swfPath + '" quality="high" pluginspage="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash"';
flashStr += 'type="application/x-shockwave-flash" width="100%" height="100%"></embed></object>';
flashDiv.innerHTML = flashStr;
}
Теперь идем в page.xaml.cs.
Подключаем пространство имен
using System.Windows.Browser;
В обработчике события на кнопку прописываем вызов нашей JavaScript-функции, с передачей трех параметров – пути к файлу и размеров.
private void ShowButton_Click(object sender, RoutedEventArgs e)
{
HtmlPage.Window.Eval("ShowSWF('galaxy.swf', 65,65);");
}
Протестируем приложение.
Видим кнопку – и при нажатии у нас показывается флеш-элемент.

Теперь осталось все это счастье закрыть.
Добавляем вторую кнопку (например одну под одной в StackPanel ), обработчик события на нее, и дописываем еще одну функцию JavaScript, которая просто скрывает этот же слой.
Кнопка в page.xaml:
<Button x:Name="HideButton" Width="90" Height="90" Click="HideButton_Click" Margin="10">
<Button.Content>
<TextBlock Text="Hide Flash" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Button.Content>
</Button>
Обработчик на кнопку в page.xaml.cs:
private void HideButton_Click(object sender, RoutedEventArgs e)
{
HtmlPage.Window.Eval("HideSWF()");
}
Функция JavaScript в Default.html:
function HideSWF() {
var flashDiv = document.getElementById("flashControlHost");
flashDiv.style.display = 'none';
}
В общем получаем такую картинку.
При желании можно отлавливать любое другое событие и вешать на него вызов этой же функции.