Архив Январь 2010
football.ua опубликовал свой тулбар на SilverLight
Сегодня на сайте football.ua появилась кастом версия браузера IE 8, которая включает в себя специально подготовленный для football.ua тулбар. Тулбар использует SilverLight 3 для отображения данных.
Смотрим:
Введение в SilverLight 4: Элемент управления ViewBox
Чтобы продемонстрировать работу нового элемента управления ViewBox, достаточно рассмотреть небольшой пример:
<UserControl x:Class="ViewBox_Chapter0.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
<Button Content="Hello" Width="400" Height="100"></Button>
</StackPanel>
</Grid>
</UserControl>
Если попробовать запустить приложение выше, и изменить размер окна браузера, то можно увидеть что размер кнопки остается неизменным. Если изменить размер окна браузера, сделав его меньшим размера кнопки, то она попросту перестанет влазить на экран. Таким образом, существует проблема изменения размеров интерфейса при изменении размеров окна браузеров. Конечно, данную проблему можно решить с помощью элемента компоновки Grid, но при работе со сложными интерфейсами, элемент Grid не помогает. Поэтому появление элемента ViewBox, позволяющего сжимать и расширять свое содержимое, является даже запоздалым.
Замечание. Элемент ViewBox был доступен и разработчикам более ранней версии SilverLight, но не входил в стандартную поставку, а поставлялся в составе специальной библиотеки с открытым кодом, разрабатываемой сообществом.
Рассмотрим пример выше, но добавим элемент компоновки ViewBox:
<UserControl x:Class="ViewBox_Chapter0.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot" Background="White">
<Viewbox MaxHeight="200" MaxWidth="800"
MinHeight="50" MinWidth="200">
<StackPanel>
<Button Content="Hello" Width="400" Height="100"></Button>
</StackPanel>
</Viewbox>
</Grid>
</UserControl>
Теперь, при изменении размеров окна браузера, также изменяется и размер нашей кнопки.
Рассмотрим элемент ViewBox более детально. Фактически тут можно выделить всего три основных свойства: Child, Stretch, StretchDirection.
Свойство Child содержит ссылку на тот элемент, размерами которого управляет ViewBox. Тут может быть только один элемент, но это может быть и контейнер (как в примере выше).
Свойство Stretch определяет, каким образом содержимое ViewBox размещается внутри выделенного пространства. Тут возможно одно из следующих значений:
· None – сохранять исходный размер контента;
· Fill – полностью заполнить элемент ViewBox, не сохраняя пропорции;
· Uniform – сохранять пропорции контента;
· UniformToFill – полностью заполнить элемент ViewBox, с сохранением пропорций контента. Естественно, что с этим параметром, в большинстве случаев, весь контент отобразить не удается и он выходит за границы ViewBox.
Последнее свойство StretchDirection позволяет разрешить только сжатие или расширение содержимого и принимает одно из значений:
· UpOnly – только расширять контент, если размер ViewBox больше размера самого контента;
· DownOnly – только сжимать контент, если размер ViewBox меньше размера самого контента;
· Both – позволяет расширять и сжимать контент (установлено по умолчанию).
Таким образом, в SilverLight 4 на один полезный элемент компоновки стало больше.
Введение в SilverLight 4: Поддержка колесика мыши
Вспоминаю те времена, когда компьютерные мыши имели всего две кнопки, а мышь с колесиком представляла собой нечто диковинное, чему сложно было найти применение. Сейчас сложно представить мышь, которая не имеет колесика. При этом наступает сильное раздражение, когда, в редких случаях, приложение не реагирует на колесико мыши. Теперь поддержка колесика мыши есть и в SilverLight.
Реализуем простое приложение, интерфейс которого содержит изображение, к которому мы применим трехмерную проекцию по оси X. Вот код интерфейса приложения:
<UserControl x:Class="MouseWheel_Chapter0.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Grid x:Name="LayoutRoot" Background="White">
<Image Source="Penguins.jpg" Width="640"
Height="480" MouseWheel="Image_MouseWheel">
<Image.Projection>
<PlaneProjection x:Name="proj"></PlaneProjection>
</Image.Projection>
</Image>
</Grid>
</UserControl>
Как видно, тут мы определили обработчик события MouseWheel, которое генерируется именно при вращении колесика мыши. Код обработчика довольно простой:
private void Image_MouseWheel(object sender, MouseWheelEventArgs e)
{
proj.RotationX += e.Delta/10;
}
Запустите приложение, щелкните на картинке и начните вращать колесико мыши – картинка будет вращаться вокруг оси X.
Нужно отметить, что все встроенные элементы, работающие с набором записей, поддерживают работу с колесиком мыши по умолчанию. Сюда относятся такие элементы как DataGrid, ListBox и др.
Введение в SilverLight 4: Поддержка уведомлений
И еще одна возможность приложений, работающих вне браузера, это возможность отображать уведомления. В данном случае под уведомлениями понимаются всплывающие окна, не требующие взаимодействия с пользователем (хотя они способны обрабатывать события от мыши, но не от клавиатуры) и исчезающие через заданный промежуток времени. Примеры таких окон можно найти, например, в приложении Microsoft Outlook, которое отображает всплывающие сообщения при получении нового письма.
Чтобы отобразить уведомление, достаточно создать объект типа NotificationWindow и установить свойство Content у созданного объекта. Свойство Content принимает любой объект, порожденный от FrameworkElement, то есть любой контейнер. После установки свойств Content, Width, Height, достаточно вызвать метод Show, принимающий время показа окна в миллисекундах.
Рассмотрим пример приложения, работающего вне браузера и отображающего примитивное окно в момент запуска. Интерфейс приложения реализуем следующим образом:
<UserControl x:Class="Notify_Chapter0.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel HorizontalAlignment="Center">
<TextBlock Text="Notification Demo"
TextAlignment="Center" FontSize="18">
</TextBlock>
<Button Name="btn" Visibility="Collapsed"
Content="Инсталировать приложение" FontSize="18"
Click="Button_Click"></Button>
<TextBlock Name="txt" Visibility="Collapsed"
TextWrapping="Wrap" TextAlignment="Center"
Text="Приложение должно быть запущено вне браузера"
FontSize="18">
</TextBlock>
</StackPanel>
</Grid>
</UserControl>
Во время запуска приложения, необходимо проверить, действительно ли приложение запущено вне браузера, и только затем приступать к созданию окна. Вот как это можно реализовать:
public MainPage()
{
InitializeComponent();
if (App.Current.IsRunningOutOfBrowser)
{
NotificationWindow notify = new NotificationWindow();
StackPanel panel = new StackPanel();
panel.Background = new SolidColorBrush(Colors.Gray);
panel.Width = 250;
panel.Height = 50;
TextBlock header = new TextBlock();
header.Text = "New message";
header.FontWeight = FontWeights.Bold;
TextBlock message = new TextBlock();
message.Text = "This is a new message";
panel.Children.Add(header);
panel.Children.Add(message);
notify.Content = panel;
notify.Width = panel.Width;
notify.Height = panel.Height;
notify.Show(10000);
}
else
{
if (App.Current.InstallState == InstallState.Installed)
{
txt.Visibility = Visibility.Visible;
}
else
{
btn.Visibility = Visibility.Visible;
}
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
App.Current.Install();
}
В результате, после запуска приложения, на экране можно увидеть следующую картину:
Как видно, уведомление отображается в системной области с небольшим отступом от нее (по 44 единицы).
Данная функциональность может быть полезна при обработке обновлений, коммуникациях, асинхронной обработке данных и др.
Введение в SilverLight 4: Управление окном приложения
Еще одна возможность приложений, работающих вне браузера, это поддержка объекта типа Window. С помощью класса Window, разработчик способен управлять окном во время работы приложения.
Естественно, что объект типа Window создается «за сценой», а разработчик может получить доступ с помощью свойства MainWindow объекта Application.
Среди основных свойств класса Window можно выделить следующие:
· Height – определяет высоту окна;
· Width – определяет длину окна;
· Left – задает отступ от левой границы экрана;
· Top – задает отступ от верхней границы экрана;
· IsActive – возвращает true, если окно активно в данный момент и находится в фокусе. В противном случае возвращает false;
· TopMost – если это свойство установлено в true, то окно всегда располагается поверх других окон (всегда находится на экране);
· WindowState – определяет состояние окна (Normal, Minimize, Maximize).
Среди методов можно выделить лишь Activate, который активирует окно приложения, выводя его на передний план и передавая ему фокус.
Стоит также отметить, что устанавливать свойства объекта, порожденного от Window можно лишь в ответ на действия пользователя (нажатие кнопки и др.) либо в обработчике события Startup объекта Application (либо до Startup).
Нужно отметить, что SilverLight 4 поддерживает специальный раздел в конфигурационном файле, позволяющий установить начальные параметры окна. Вот как может выглядеть часть конфигурационного файла с установленными параметрами:
<OutOfBrowserSettings>
<OutOfBrowserSettings.WindowSettings>
<WindowSettings Title="My Window"
Left="double" Top="double"
Height="double" Width="double" />
</OutOfBrowserSettings.WindowSettings>
</OutOfBrowserSettings>
Введение в SilverLight 4: RechTextArea элемент управления
Описывая очередную возможность SilverLight 4 почему-то вспомнился лозунг: «Перед использованием – доработать напильником». Действительно, если смотреть на предыдущие посты, то вроде бы функционал и есть, но чего-то все время не хватает. Есть возможность определить контекстное меню, но инфраструктуры для такого меню нет, хотя инфраструктура есть даже для подсказок, есть возможность работать с буфером обмена, но с жесткими ограничениями, есть возможность отображать HTML, но только для приложений, работающих вне браузера. Не исключением является и новый элемент управления, который сразу попал в стандартную поставку SilverLight 4, это RichTextArea.
Уже пару лет разработчики пытаются добиться элемента управления, который бы позволил отображать форматированный текст. Пусть это будет DOCX, RTF, XPS или PDF, это не столь принципиально. Большинство текстовых редакторов спокойно преобразуют текст из одного формата в другой. Вместо ожидаемого элемента разработчикам предоставили RichTextArea, который действительно способен отображать текст с минимальным форматированием, но в своем, только ему понятном, формате. Давайте посмотрим в каком именно.
Ниже пример элемента RichTextArea, отображающего текст с минимальный форматированием:
<RichTextArea HorizontalAlignment="Left"
Name="rArea" VerticalAlignment="Top"
Height="300" Width="400" >
<Paragraph>
<Bold>This is a bold text</Bold>
<LineBreak></LineBreak>
<Underline>This is an underline text</Underline>
<LineBreak></LineBreak>
<Italic>This is an italic text</Italic>
<LineBreak></LineBreak>
This is a button:
<InlineUIContainer>
<Button Content="Button"></Button>
</InlineUIContainer>
</Paragraph>
</RichTextArea>
В результате на экране отобразится следующий контент:
Как видно, RichTextArea является контейнером для других элементов. Так основным наполнением элемента RichTextArea является набор элементов Paragraph, который описывает параграф текстового документа. В свою очередь параграф может включать набор из следующих элементов:
· Run – задает обычный текст;
· Span – служит для группировки других элементов;
· Bold – определяет жирное начертание символов;
· LineBreak – переход на другую строку;
· Italic – определяет рукописное начертание символов;
· Underline – текст с подчеркиванием;
· HyperLink – создает гиперссылку, которая становится активной только в режиме ReadOnly элемента RichTextArea;
· InlineUIContainer – позволяет вставить в документ любой из элементов, порожденных от UIElement.
Естественно, создавать и заполнять RichTextArea можно и программно. Вот небольшой пример кода:
Bold b = new Bold();
b.Inlines.Add("This is a bold text");
Italic i = new Italic();
i.Inlines.Add("This is an italic text");
Underline u = new Underline();
u.Inlines.Add("This is an underline text");
Paragraph myPar = new Paragraph();
myPar.Inlines.Add(b);
myPar.Inlines.Add(new LineBreak());
myPar.Inlines.Add(i);
myPar.Inlines.Add(new LineBreak());
myPar.Inlines.Add(u);
rArea.Blocks.Add(myPar);
Таким образом, RichTextArea является элементом с минимальным интерфейсом, где всю работу необходимо выполнить программисту. Конечно, Вы можете найти примеры готовых методов, позволяющих сохранить и загрузить содержимое RichTextArea, или реализацию удобного интерфейса пользователя (вот один из примеров: http://channel9.msdn.com/learn/courses/Silverlight4/RichTextEditor), но много нужно будет сделать самостоятельно.
Введение в SilverLight 4: WebBrowser и HtmlBrush элементы управления
Когда я услышал об очередной возможности SilverLight – отображение HTML, то конечно же сильно обрадовался. Ведь это позволило бы разработчикам использовать уже наработанные XML, вместе с XSLT-преобразованием, для отображения отформатированного содержимого (говорят, что слово контент – это уже русское слово, поэтому дальше буду использовать контент). Однако, все оказалось немного более печально, чем в анонсах. Возможность отображения HTML действительно появилась, но работает только для приложений вне браузера (Out Of Browser). И это очень странно. Ведь если речь идет об Internet-приложениях, то вряд ли конечный пользователь будет что-то устанавливать себе на машину, не поработав предварительно с приложением в окне браузера. Корпоративный сектор – да, но тут можно использовать и WPF (а то и Win Forms), который к тому же и быстрее. А учитывая способ инсталяции приложений вне браузера (ведь их нельзя отправить по электронной почте или указать ссылку на инсталяцию), разработчики получают дополнительную головную боль при разработке «двух» версий одного приложения (в браузере и вне браузера). Фактически речь будет идти об одной версии, но с различным поведением, в зависимости от способа запуска.
Как бы то не было, но если Вы разрабатываете приложение, работающее вне браузера, то можете использовать элемент управления WebBrowser, расположенный в стандартной сборке System.Windows.dll.
При создании элемента WebBrowser, необходимо явно установить Height и Width свойства, так как по умолчанию они установленны в 0. Также важным свойством является Source, позволяющее установить адрес страницы. Чаще всего это свойство используется для установки начального значения в XAML-файле, но может быть полезно и для получения текущего адреса. Особое внимание нужно обратить на то, что страница, отображаемая в WebBrowser, должна находиться в домене SilverLight-приложения (даже после установки на компьютер пользователя ощущается боязнь DOS-атак у разработчиков этой функциональности). Для отображения HTML-контента в процессе работы приложения, можно использовать один из двух методов:
· Navigate – действие этого метода аналогично установке свойства Source, то есть элемент WebBrowser отобразит страницу, если она находится в домене приложения. Если Вы хотите отобразить внешний контент, то необходимо разместить ссылку на него внутри элемента iframe;
· NavigateToString – этот метод более универсален и позволяет отобразить любой HTML-контент в виде текстовой строки.Это означает, что если Вы хотите отобразить внешний контент, то просто формируете строку, содержащую iframe и указываете ссылку на страницу (независимо от домена).
Ниже показан пример приложения, которое позволяет осуществлять навигацию на любую страницу из SilverLight-приложения.
Интерфейс приложения, содержащий WebBrowser и элементы навигации:
<UserControl x:Class="HTML_Chapter0.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<StackPanel x:Name="LayoutRoot" Background="White">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<TextBox Name="urlText"
Text="http://www.microsoft.com" Width="300">
</TextBox>
<Button Content="Navigate" Click="Button_Click"></Button>
</StackPanel>
<WebBrowser Height="800" Width="1024" Name="webBrowser">
</WebBrowser>
</StackPanel>
</UserControl>
А вот и код, осуществляющий навигацию:
private void Button_Click(object sender, RoutedEventArgs e)
{
webBrowser.NavigateToString(
String.Format(
"<iframe height=800 width=1024 src={0}></iframe>",
urlText.Text));
}
При этом не забудьте сконфигурировать приложение как работающее вне браузера (и установить его после запуска на локальную машину).
Использование iframe позволяет не только отобразить HTML, который находится вне домена приложения, но и внедрить элемент <object>. Это автоматически означает, что SilverLight-приложения с легкостью могут содержать в себе Flash-приложения (например, отображать ролики с youtube).
Нужно еще отметить возможность принудительно выполнять Java-скрипты, содержащиеся в WebBrowser элементе. Для этого используется метод InvokeScript.
В завершении раздела отмечу, что HTML можно использовать в качестве заливки для любого элемента, поддерживающего работу с Brush. Для этих целей существует специальный класс HtmlBrush, который в качестве источника принимает объект WebBrowser.
Введение в SilverLight 4: Работа с буфером обмена
Следующая возможность позволяет получить доступ к буферу обмена. Пока речь идет только о работе с текстом, но в будущем (возможно к релизу), эта функциональность будет расширена, и пользователь сможет вставлять и копировать также и изображения.
Механизм работы с буфером реализован в двух вариантах:
· Копирование и вставка текста с помощью горячих клавишь (Ctrl+C, Ctrl+V) при работе с такими элементами как TextBox, RichTextBox и т. д. Как реализован этот механизм и как воссоздать его в своем элементе управления – пока остается загадкой. Ведь Ctrl+C, Ctrl+V работают тут без каких-либо разрешений от пользователя, то есть работают всегда, в отличии от второго механизма;
· Доступ к буферу обмена с помощью статического класса Clipboard, содержащего три статических метода:
· ContainsText – проверяет наличие текста в буфере обмена;
· GetText – позволяет получить текст из буфера обмена;
· SetText – сохраняет текст в буфере обмена.
Данный класс можно использовать только в ответ на событие инициированное пользователем, например, нажатие кнопки. При этом пользователь получит сообщение о том, что приложение пытается получить доступ к буферу обмена, и сможет заблокировать или предоставить доступ. Если пользователь блокирует доступ к буферу, то генерируется исключение SecurityException. Что интересно, если пользователь блокирует доступ при первой попытке, то исключение будет генерироваться всякий раз при попытке вызвать методы класса Clipboard, но сообщение пользователь видеть уже не будет. Механизма отобразить пользователю сообщение еще раз я не нашел. Еще одна загадка данной функциональности.
Реализуем простой пример, содержащий поле редактирования и две кнопки:
MainPage.xaml
<UserControl x:Class="Clipboard_Chapter0.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<StackPanel x:Name="LayoutRoot" Background="White">
<TextBox Height="92" Name="textBox1" Width="339"
AcceptsReturn="True"
HorizontalScrollBarVisibility="Auto" />
<Button Content="Copy" Height="23"
Name="copyButton" Width="75"
Click="copy_Click" />
<Button Content="Past" Height="23"
Name="pasteButton" Width="75" Click="past_Click" />
</StackPanel>
</UserControl>
MainPage.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Security;
namespace Clipboard_Chapter0
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void past_Click(object sender, RoutedEventArgs e)
{
try
{
if (Clipboard.ContainsText())
textBox1.Text = Clipboard.GetText();
}
catch (SecurityException ex)
{
textBox1.Text = "You didn't grant permissions!";
}
}
private void copy_Click(object sender, RoutedEventArgs e)
{
try
{
Clipboard.SetText(textBox1.Text);
}
catch (SecurityException ex)
{
textBox1.Text = "You didn't grant permissions!";
}
}
}
}
Введение в SilverLight 4: правая кнопка мыши
Еще с выходом SilverLight 1, многие разработчики начали жаловаться на то, что не могут реализовать собственное контекстное меню при нажатии правой кнопки мыши в своем приложении. Действительно, правая кнопка полностью принадлежала SilverLight, а пользователь мог вызвать только контекстное меню, позволяющее получить доступ к настройкам встраиваемого компонента.
SilverLight 4 позволяет полностью переопределить поведение при нажатии правой кнопки. При этом программист вовсе не обязан отображать меню. Действие может полностью зависеть от самого приложения.
Чтобы переопределить работу правой кнопки мыши, достаточно выполнить два действия:
· Отключить существующее меню. Для этого нужно определить обработчик с события MouseRightButtonDown и установить свойство Handled в true. Это сигнализирует о том, что мы берем обработку события на себя и стандартное меню отображать не нужно;
· Определить вызов собственного меню (или любые другие действия) в обработчике события MouseRightButtonDown.
Расширим функционал предыдущего приложения, добавив контекстное меню к изображениям на панели. Для этого, расширим метод photoPanel_Drop, добавив следующий код:
img.MouseRightButtonDown += new
MouseButtonEventHandler(img_MouseRightButtonDown);
img.MouseRightButtonUp += new
MouseButtonEventHandler(img_MouseRightButtonUp);
Теперь реализуем сами обработчики событий. Начнем с MouseRightButtonDown:
void img_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
}
Как видно, тут нет ничего сложного. Мы просто нотифицируем SilverLight о перехвате события правой кнопки и подавляем отображение стандартного контекстного меню.
Теперь реализуем MouseRightButtonUp. Тут есть проблема, которая состоит в том, что если Вы хотите отобразить меню, то его нужно реализовать самостоятельно, или обратиться к сторонним разработчикам за дополнительными компонентами. В списке стандартных компонент и в SDK контекстное меню пока не реализовано. Я не стал разрабатывать меню сам, а установил тестовую версию с сайта: http://www.telerik.com. Тут Вы можете найти множество элементов управления для SilverLight 4.
Замечание. Никогда не используйте контекстное меню от Telerik так, как показано ниже. Компонент достаточно «умный», чтобы отобразить меню в качестве реакции на какое-то событие. Кроме того, этот элемент можно ассоциировать с любым интерфейсным элементом в момент его создания. Но, если сделать все правильно, то обработчик события для правой кнопки мыши и не понадобитсяJ Поэтому будем создавать меню именно при нажатии правой кнопки мыши и уничтожать его в «ручном» режиме.
private Image menuImage;
private RadContextMenu contextMenu;
void img_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
menuImage = (Image)sender;
if (contextMenu != null)
{
photoPanel.Children.Remove(contextMenu);
}
contextMenu = new RadContextMenu();
contextMenu.Items.Add("Delete");
contextMenu.Items.Add("Close Menu");
Point p=e.GetPosition(photoPanel);
contextMenu.Margin = new Thickness(p.X, p.Y, 0, 0);
photoPanel.Children.Add(contextMenu);
contextMenu.ItemClick += new
Telerik.Windows.RadRoutedEventHandler(menu_ItemClick);
}
void menu_ItemClick(object sender,
Telerik.Windows.RadRoutedEventArgs e)
{
RadRoutedEventArgs args = e as RadRoutedEventArgs;
RadMenuItem menuItem = args.OriginalSource as RadMenuItem;
string tag = Convert.ToString(menuItem.Header);
switch (tag)
{
case "Delete":
photoPanel.Children.Remove(menuImage);
photoPanel.Children.Remove(contextMenu);
break;
case "Close Menu":
photoPanel.Children.Remove(contextMenu);
break;
}
contextMenu = null;
}
В коде выше я реализовал механизм создания нового контекстного меню, а также механизм обработки события, связанного с выбором пункта меню. Частично продублировал работу, уже реализованную в компоненте, но…
Ниже показан снимок экрана во время работы приложения.
Введение в SilverLight 4: Печать
Одна из важных и фундаментальных возможностей, которая должна значительно расширить возможности SilverLight-приложений, это печать.
Для демонстрации возможности печати, будем использовать пример из предыдущего поста, определив обработчик события Click для кнопки printButton, объект типа PrintDocument и обработчик события PrintPage. Вот как будет выглядеть наш код:
private PrintDocument printDoc;
public MainPage()
{
InitializeComponent();
printDoc.PrintPage += new
EventHandler<PrintPageEventArgs>(printDoc_PrintPage);
}
void printDoc_PrintPage(object sender, PrintPageEventArgs e)
{
e.PageVisual = photoPanel;
e.HasMorePages = false;
}
private void printButton_Click(object sender, RoutedEventArgs e)
{
printDoc.DocumentName = "Images";
printDoc.Print();
}
Как видно из этого примера, за печать в SilverLight отвечает класс PrintDocument, объект которого мы создали в коде выше. Объект этого класса способен генерировать три события: StartPrint, EndPrint и PrintPage. Первые два события позволяют провести предварительную подготовку к печати и получить информацию об успешном завершении печати соответственно. А вот обработчик события PrintPage как раз и выполняет всю черновую работу. Задача обработчика события PrintPage получить параметры страницы (тут только длина и ширина отображаемой области), используя параметр типа PrintPageEventArgs, сформировать содержимое страницы и отправить ее на печать. При этом управление печатью нескольких страниц происходит с помощью свойства HasMorePages.
Фактически, объект типа PrintDocument способен печатать любой элемент, порожденный от UIElement, то есть, для печати страницы Вы можете выбрать любой из контейнеров, расположить в нем свои элементы и передать ссылку на этот контейнер с помощью свойства PageVisual. В примере выше, мы не формировали специальную страницу для печати, а просто использовали существующий контейнер, отображающий наши картинки.
