Цель лекции: показать историю развития платформы Silverlight и дать понимание дальнейшей тенденции. Изложить структуру и возможности Silverlight 4 по разработке интерактивных интернет-приложений нового поколения. Продемонстрировать новые возможности Silverlight 5, реализованные в версии
В настоящее время доступны четыре версии
Silverlight 1. Это выпуск Silverlight не имел общеязыковой среды выполнения. Он поддерживал небольшое подмножество XAML и множество возможностей, которые предвещали будущее Silverlight. Возможно самый очевидный аспект Silverlight 1 – то, что приложения написаны или полностью на XAML или в смеси с JavaScript и объектной моделью документов, чтобы управлять интерфейсом пользователя. Так как нет общеязыковой среды выполнения, нет фазы компиляции, и JavaScript интерпретируется на клиентской стороне.
Silverlight 2. Вскоре после того, как вышел Silverlight 1, был выпущен предварительный релиз следующей версии Silverlight. Этот выпуск был известен как Silverlight 1.1, наиболее значительным аспектом которого является
Silverlight 3. В марте 2009 Microsoft выпустила бета-версию Silverlight 3. В июле 2009 появилась среда разработки Expression Blend 3. Silverlight 3 является расширением Silverlight 2 и главным образом обеспечивает усовершенствование возможностей графики, управления медиа, области разработки приложений (дополнительные элементы управления, усовершенствованная поддержка связывания элементов управления с данными, поддержка внебраузерных приложений), а также интеграцию с Expression Blend.
Silverlight 4. Microsoft главным образом фокусировалась на возможностях, управляемых медиа до версии Silverlight 3. Silverlight 3 представил ключевые возможности
Бета-версия Silverlight 4 была быстро выпущена в ноябре 2009, а окончательный релиз Silverlight 4 появился 12 апреля 2010 во время конференции DevConnection. Детальный разбор архитектуры программной платформы Silverlight 4 был приведен во второй лекции.
Silverlight 4 имеет следующие ключевые особенности:
Возможность для приложений Silverlight быть "доверенными" так же, как внебраузерные приложения открывает многие возможности, которые обеспечивают традиционные WPF-приложения, которые могут вызывать "родной" код за пределами "песочницы" на клиентской машине:
Silverlight 4 действительно включает несколько ключевых расширений, чтобы защитить, обработать и доставить более дружественные с медиа
Следующие усовершенствования основной платформы и компонентов помогут улучшить интерфейс конечного пользователя и разрабатывать корпоративные приложения в режиме быстрой разработки.
Рассмотрим ожидаемые возможности релиза.
Даже Silverlight 4 не работает в 64-битных браузерах. Между тем, 32-бита уверенно уходят в прошлое. Именно поэтому, начиная с 5-й версии Silverlight, плагин будет доступен как в 32-битной, так и в 64-битной версиях. Предполагается, что пользователю не придется думать, какая из версий должна быть установлена.
Речь идет о том, что при просмотре видео с помощью Silverlight (а, следовательно, при отсутствии взаимодействия с мышью и клавиатурой), Вас не застанет врасплох установленный на машине
В Silverlight 4 появился класс
Речь идет не о технологии псевдо 3D, появившейся в Silverlight 4, а о полноценном 3D API с поддержкой аппаратного ускорения. Последнее уже хорошо зарекомендовало себя при работе с видео.
Поддержка Behaviors призвана перенести функциональность Поведений, реализованных в Blend, на уровень ядра Silverlight. Речь идет о создании комплексных объектов, объединяющих в себе ряд различных преобразований, создавая тем самым уникальное Поведение. И если ранее подобное можно было реализовать, только подключив специальную сборку из Blend, то теперь это все будет в ядре. Введение триггеров призвано еще больше сблизить WPF и Silverlight, хотя триггеры в Silverlight выглядят более универсальными.
В Silverlight 5 любому контейнеру будет можно задавать эффекты, связанные с заполнением контейнера и добавлением нового элемента. Благодаря Layout transition разработчику не придется работать с каждым элементом отдельно, а достаточно будет указать механизм заполнения для всего контейнера.
У разработчиков теперь будет меньше головной боли, так как появилась возможность ставить точки останова в коде, описывающем связывание данных. Достаточно поставить точку останова в XAML файле, на строке, описывающей Binding, и разработчик может получить всю возможную информацию о связывании и проблемах, возникающих с этим. Поэтому найти такие ошибки, как неправильное написание имени свойства или имени преобразователя типов, станет теперь проще.
FindAncestor позволяет выполнять связку, выполняя поиск любого вышестоящего элемента, и выполнять с ним связывание.
Как видно, Silverlight 5 все ближе и ближе приближается к WPF. Новое событие DataContextChanged позволит определить изменение источника данных при связывании.
Связывание теперь можно будет использовать в
Silverlight 5 будет поддерживать правила, установленные групповыми политиками. Поддержка групповых политик позволит централизовано управлять развертыванием Silverlight-приложений. Кроме того, это даст возможность устанавливать список Publishers, разрешая избранным приложениям работать внутри браузера, но с использованием Full-Trust со всеми вытекающими последствиями (включая поддержку элемента WebBrowser). Это нововведение связано с отзывом от некоторых компаний, которые хотят запускать свои корпоративные приложения внутри браузера, но с повышенными привилегиями.
Обычно требуется реализовать обработчик события при двойном щелчке, но Silverlight позволяет обрабатывать и большее количество нажатий. Речь идет как о левой, так и о правой кнопках мыши. Тут разработчики немного схитрили. Чтобы не менять модель событий и не вводить новые события на двойной щелчок мыши, к параметру EventArgs уже существующих событий, возникающих при однократном нажатии кнопки мыши, было добавлено свойство ClickCount. Это свойство и содержит количество нажатий.
Интересно то, что события MouseLeftButtonDown и MouseRightButtonDown срабатывают для каждого щелчка, даже если вы хотите обрабатывать только двойной щелчок. При этом, если между щелчками проходит больше секунды, или другое событие (например, пользователь еще и потянул мышь), то счетчик обнуляется. Поэтому, если Вы хотите для одного и того же объекта обрабатывать одинарный и двойной (а может и тройной) щелчок, то необходимо, чтобы они не были взаимоисключающими. Иными словами, при одинарном щелчке Вы можете выбрать папку, а при двойном – открыть папку. Наоборот работать не будет, так как уже при первом щелчке папка будет открыта.
Ниже показан простой код, который позволяет отобразить количество щелчков:
<Grid x:Name="LayoutRoot" Background="White"
MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown">
<sdk:Label Height="28" HorizontalAlignment="Left"
Name="label1" VerticalAlignment="Top" Width="120" />
</Grid>
Данный функционал достаточно простой, но приятный. Вспомните бесконечные элементы ComboBox со списком стран, или элементы, позволяющие установить фильтр по чьей-то фамилии, выбрав ее из сотни других и т. д. Для всех этих случаев, имея элемент-наследник от ItemsControl, такой как ListBox, ComboBox и другие, Вы всегда должны были пользоваться скроллингом, чтобы найти нужный элемент (это утверждение относится к Silverlight). В WPF или даже в простом HTML, подобные элементы давно поддерживают возможность выбора с клавиатуры. Так, переходя на тот же выпадающий список стран, мне достаточно легко набрать на клавиатуре букву "Р", чтобы увидеть активным элементом слово "Россия". Это позволяет быстро заполнять сложные формы с большим количеством опций. Теперь такая возможность появилась и в Silverlight. Рассмотрим простой пример:
<Grid x:Name="LayoutRoot" Background="White">
<ComboBox Height="23" HorizontalAlignment="Left"
Name="comboBox1" VerticalAlignment="Top" Width="120">
<ComboBoxItem Content="Последний" />
<ComboBoxItem Content="Третий" />
<ComboBoxItem Content="Второй" />
<ComboBoxItem Content="Первый" />
</ComboBox>
</Grid>
На экране отобразится обычный ComboBox, который позволяет выбрать один из четырех элементов. Переключитесь на русскую клавиатуру и попробуйте понажимать символ "П". ComboBox будет последовательно выбирать один из двух элементов (Первый и Последний). Если Вы последовательно наберете два символа, например "Пе", то будет выбран "Первый" без альтернатив.
Понятно, что ComboBox в Silverlight, как и другие ItemsControl, позволяет отображать что угодно и не обязательно текст, особенно если речь идет о связывании со сложными объектами. Именно поэтому, для всех элементов ItemsControl ввели дополнительное свойство TextPath, которое задает имя свойства объекта, с которым мы реализуем связывание, используемое при выборе элемента с клавиатуры.
<ComboBox Height="23" TextSearch.TextPath="ImageTitle"
HorizontalAlignment="Left" Name="comboBox1"
VerticalAlignment="Top" Width="120">
В предыдущих версиях Silverlight, приложения, которые получали возможность работать вне браузера, могли претендовать на дополнительные (повышенные) привилегии. Это позволяло подобным приложениям получать доступ к диску, расширять изолированное хранилище без уведомления пользователя, реализовывать доступ к клавиатуре в полноэкранном режиме и многое другое. Между тем, многие разработчики желали бы иметь подобную функциональность и для приложений, работающих в браузере. Естественно речь идет о корпоративных приложениях, которые доступны только сотрудникам филиалов и при этом могут часто обновляться. В связи с этим в Silverlight 5 появилась возможность создавать приложения с повышенными полномочиями, работающими в окне браузера. Рассмотрим процедуру создания таких приложений.
Приложение необходимо подписать сертификатом, что вполне можно сделать из оболочки Visual Studio в настройках проекта (рис. 7.1).
(рис 7.1) Вкладка Signing
Тут вы можете сгенерировать тестовый сертификат или выбрать его из хранилища (файла). Теоретически, если вы создаете приложение для работы внутри своей сети, сертификат можно и не покупать, а пользоваться тестовым.
Далее необходимо развернуть сертификат на машинах, где будет работать ваше Silverlight-приложение. Если вы хотите протестировать функциональность на рабочей машине, то это можно легко сделать, нажав кнопку More Details… в диалоге выше, перейдя к параметрам сертификата (рис. 7.2):
(рис 7.2) Вкладка General
На следующем этапе нужно у всех клиентов разрешить запуск приложений в браузере с повышенными полномочиями. Это можно сделать, установив значение AllowElevatedTrustAppsInBrowser (DWORD) в 0х00000000 (disabled) или 0?00000001 (enabled) в ключах HKEY_LOCAL_MACHINE\Software\Microsoft\Silverlight\ (для 32 бит) или HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Silverlight\ (для 64 бит).
Необходимо внести изменения в конфигурационный файл таким образом, чтобы ваше приложение при работе с браузером запрашивало дополнительные полномочия. Это легко можно сделать в настройках проекта, выбрав соответствующую галочку (рис. 7.3):
(рис 7.3) Вкладка Silverlight
После этих действий, Visual Studio сгенерирует дополнительный конфигурационный файл следующего содержимого:
<InBrowserSettings>
<InBrowserSettings.SecuritySettings>
<SecuritySettings ElevatedPermissions="Required" />
</InBrowserSettings.SecuritySettings>
</InBrowserSettings>
Теперь ваши приложения (подписанные сертификатом), будут запускаться в браузере с дополнительными полномочиями, включая полную поддержку клавиатуры в полноэкранном режиме, поддержку элементов WebBrowser и NotificationWindow и др.
Хочется отметить, что если вы попробуете тестировать эту процедуру, запуская приложение через localhost, то первые три шага игнорируются. Поэтому не попадите в заблуждение: если на вашей машине работает, то будет работать и на других.
Для приложений с повышенными привилегиями, работающих вне браузера, стало возможным отображать несколько немодальных окон, которые могут перемещаться за пределы родительского окна, а также интегрируются с панелью задач Windows 7.
Ниже приведен небольшой код, который, внутри конструктора главного окна, генерирует дочернее окно и делает его видимым:
public MainPage()
{
InitializeComponent();
Window childWindow = new Window();
childWindow.Height = 400;
childWindow.Width = 600;
childWindow.Top = 30;
childWindow.Left = 30;
childWindow.Title = "Child Window";
childWindow.Visibility = Visibility.Visible;
}
В данном примере дочернее окно создается с размерами 600 на 400, при этом верхний левый его угол будет находиться в позиции (30, 30), относительно экрана системы (не родительского окна). При этом обратите внимание на то, что созданное окно поддерживается панелью задач Windows 7 (рис. 7.4):
(рис 7.4) Поддержка нескольких окон в Silverlight 5
Технология Silverlight 4 поддерживала возможность приложениям с повышенными привилегиями получать доступ к файловой системе пользователя. Правда, доступ был ограничен лишь несколькими папками. Так, в режиме с повышенными привилегиями, приложения получают полный контроль к специальным папкам, ассоциированным с пользователем: MyDocuments, MyVideos, MyPictures, MyMusic. Пути к указанным папкам можно получить, используя статический класс Environment. При этом нужно отметить, что SilverLight-приложение работает только с папками, но не с библиотеками (Windows 7).
В Silverlight 5 появилась возможность взаимодействовать со всей файловой системой пользователя. Речь идет как о чтении файлов, так и о записи.
Теперь при вызове этого диалогового окна, можно установить имя файла (как и список расширений), которое будет отображаться по умолчанию, как имя файла, предлагаемого для записи. Вот как это выглядит:
SaveFileDialog dialog = new SaveFileDialog(); dialog.DefaultFileName = "hello.txt"; dialog.ShowDialog();
Кроме описанной возможности, появилось свойство InitialDirectory, позволяющее задать директорию, которая будет открыта в диалоге по умолчанию.
В Silverlight 5 стала доступна библиотека по работе с Media. Классы этой библиотеки представлены пространством имен Microsoft.Xna.Framework.Audio. Нетрудно догадаться, что данный шаг выполнен в рамках интеграции с XNA библиотеками, которые можно использовать и в Silverlight (это аудио и 3D).
Новое пространство имен содержит два основных класса, позволяющих создавать аудио эффекты в процессе работы Silverlight приложения. Файлы, доступные для проигрывания, должны быть в формате WAV и могут быть загружены с помощью класса SoundEffect. Конструктор этого класса получает ссылку на набор данных и (или) настройки аудио. Создание конкретного экземпляра можно также выполнить с помощью статического метода FromStream, получающего ссылку на поток в качестве параметров. Проигрывание эффекта осуществляется с помощью метода Play. Каких-то других методов SoundEffect не имеет, но это вовсе не означает, что отдельно взятым объектом нельзя управлять. Так, если вы хотите не просто воспроизвести эффект, но и добавить элементы управления аудио (громкость, пауза и т .д.), то вместо метода Play следует вызывать метод CreateInstance, создающий конкретный экземпляр на базе SoundEffect, и возвращающий ссылку типа SoundEffectInstance, которая позволит управлять нашим аудио файлом.
SoundEffect sEffect=SoundEffect.FromStream(streamInfo.Stream); sEffect.Play();
В Silverlight 5 произошли улучшения и в MediaElement элементе. Теперь этот элемент управления содержит такое свойство как PlaybackRate и событие RateChanged. Свойство позволяет задавать скорость проигрывания, синхронизировать видео и звук, а также выполнять "переметку" не только вперед, но и назад. Предполагается, что можно будет использовать следующие множители для скорости проигрывания: 0.2, 0.4, 0.6, 0.8, 1, 2, 4, 8, 16, 32. Событие RateChanged позволит реагировать на изменение свойства.
Silverlight 5 поддерживает и работу с пультом. Данная функциональность стала доступна благодаря поддержке события MediaCommand, которое доступно у всех UIElement. Иными словами, если вы хотите обрабатывать нажатия кнопок пульта, то Вам следует обработать это событие у родительского контейнера (от дочерних элементов оно как раз туда и свалится). Чтобы понять, какая кнопка на пульте была нажата, обработчик события получает доступ к свойству в MediaCommandEventArgs, содержащему свойство MediaCommand. Последнее и содержит информацию по нажатой кнопке.
Silverlight 5 предлагает несколько интересных возможностей при работе с текстом. Так, элементы управления Control, TextBlock и TextElement, имеют новое свойство CharacterSpacing. Это свойство позволяет установить расстояние между символами внутри текста.
Свойство LineHeight позволяет установить ширину строки (можно интерпретировать, как расстояние между строками) и определено в таких элементах как Block, TextBlock, TextBox и RichTextBox. Для элемента RichTextBox можно также задать стратегию с помощью свойства LineStackingStrategy. На рис. 7.5 пример текста внутри элемента TextBlock с расстоянием между строками 30 и расстоянием между символами – 200:
(рис 7.5) Пример возможности TextBlock в Silverlight 5
Наконец, Silverlight 5 стал поддерживать два новых текстовых элемента, это RichTextBlock и RichTextBlockOverflow. Эти элементы аналогичны элементам RichTextBox и RichTextBoxOverflow, но позволяют отображать текст только на чтение.
Рассмотрим небольшой пример с элементом RichTextBlockOverflow:
<StackPanel x:Name="LayoutRoot" Background="White"
Orientation="Horizontal" VerticalAlignment="Top">
<RichTextBlock
Width="250" FontSize="16" OverflowContentTarget=
"{Binding ElementName=SecondBox}">
<Paragraph>
В лесу родилась елочка,
</Paragraph>
. . . . . . . . //повторить 20 разJ
</RichTextBlock>
<RichTextBlockOverflow Width="250" Name="SecondBox">
</RichTextBlockOverflow>
</StackPanel>
Результат работы этого кода показан на рис. 7.6:
(рис 7.6) Пример с элементом RichTextBlockOverflow в Silverlight 5
Как видно, RichTextBlockOverflow может отображать текст, который не "вмещается" в основной элемент RichTextBlock. Благодаря таким элементам мы можем размещать текст в 2, 3 и более колонках (или реализовывать более сложные сценарии).
Silverlight 5 позволяет теперь не только реализовать растровую, но и векторную печать. Для этих целей используется все тот же метод Print класса PrintDocument, который осуществляет попытку печати в векторном формате, а в случае неудачи (принтер не поддерживает), перейти к печати в растровом виде. Растровую печать можно инициировать с помощью нового метода PrintBitmap.
В документации эта возможность пока не описана, но она уже реализована – возможность вызова методов Windows API из Silverlight приложений, обладающих повышенными полномочиями. Причем речь идет о приложениях, которые работают как в браузере, так и вне браузера. Поскольку вызов нативных функций в .NET обычно осуществляется с помощью атрибута DllImport. Запустим приложение с повышенными привилегиями:
public partial class MainPage : UserControl
{
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd,
String text, String caption, uint type);
public MainPage()
{
MessageBox(new IntPtr(0), "Hello World!", "Hello Dialog", 0);
InitializeComponent();
}
}
На экране поверх браузера вы увидите стандартный MessageBox.
Современный отладчик в Visual Studio давно позволяет разработчику получать всю необходимую информацию, если речь идет о коде на C#, C++ или даже JavaScript. Но как только речь заходит о XAML, то тут механизмы отсутствуют. Казалось бы, зачем нужна отладка в XAML, если тут идет декларативное описание интерфейса приложения. Действительно, отладка в XAML не нужна, если речь не идет о связывании с данными. Небольшой кусок кода, связывающий наши данные и интерфейс, может вызвать массу проблем при отладке. Ведь причин для возникновения проблем при связывании может быть множество, это и отсутствие какого-либо свойства, и проблемы с преобразованием либо же
Рассмотрим небольшой пример кода на XAML:
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
xmlns:d=http://schemas.microsoft.com/expression/blend/2008
xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006
Loaded="UserControl_Loaded"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.Resources>
<Style TargetType="TextBox">
<Setter Property="Background" Value="AliceBlue"></Setter>
<Setter Property="Width" Value="200"></Setter>
<Setter Property="Margin" Value="5"></Setter>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="5"></Setter>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="First Name:" Grid.Column="0" Grid.Row="0"/>
<TextBlock Text="First Name:" Grid.Column="0" Grid.Row="1"/>
<TextBlock Text="First Name:" Grid.Column="0" Grid.Row="2"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding FisrtName}"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding LastName}"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Age}"/>
</Grid>
</UserControl>
В результате мы получим небольшую формочку, которая позволяет заполнить три поля. Код, необходимый для работы формы, может выглядеть так:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Person p = new Person();
p.FirstName = "Sergey";
p.LastName="Baydachnyy";
p.Age = 33;
LayoutRoot.DataContext = p;
}
И класс Person:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
Запустив это приложение, можно убедиться, что первое поле не было заполнено данными. Чтобы понять причину ошибки, достаточно установить Breakpoint в XAML файле на строку, описывающую связывание в первом поле, и запустить приложение в режиме отладки. Вот что можно увидеть в окне Locals:
(рис 7.7) Отладка XAML в Silverlight 5
Тут и информация об ошибке (ошибка намеренно сделана в имени поля) и данные об объекте и т. д. То есть, сгенерированный объект BindingState четко позволяет выявить проблему и проверить правильность данных.
Данная поддержка состоит в расширении TextBox, то в случае двунаправленного связывания, при изменении элемента TextBox, источник мог быть обновлен лишь при потере фокуса или явным образом. Значение PropertyChanged позволяет реагировать на любые изменения в текстовом поле "на лету". При этом нет необходимости обрабатывать нажатия клавиш и т .д. Вот пример кода:
1: <UserControl x:Class="SilverlightApplication1.MainPage"
2: xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
3: xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
4: xmlns:d=http://schemas.microsoft.com/expression/blend/2008
5: xmlns:mc=http://schemas.openxmlformats.org/markup-ompatibility/2006
6: Loaded="UserControl_Loaded"
7: mc:Ignorable="d"
8: d:DesignHeight="300" d:DesignWidth="400">
9:
10: <Grid x:Name="LayoutRoot" Background="White">
11: <Grid.Resources>
12: <Style TargetType="TextBox">
13: <Setter Property="Background" Value="AliceBlue"/>
14: <Setter Property="Width" Value="200"/>
15: <Setter Property="Margin" Value="5"/>
16: </Style>
17: <Style TargetType="TextBlock">
18: <Setter Property="Margin" Value="5"/>
19: </Style>
20: </Grid.Resources>
21: <Grid.RowDefinitions>
22: <RowDefinition Height="Auto"></RowDefinition>
23: <RowDefinition Height="Auto"></RowDefinition>
24: </Grid.RowDefinitions>
25: <Grid.ColumnDefinitions>
26: <ColumnDefinition Width="Auto"></ColumnDefinition>
27: <ColumnDefinition Width="Auto"></ColumnDefinition>
28: </Grid.ColumnDefinitions>
29:
30: <TextBlock Text="First Name:" Grid.Column="0" Grid.Row="0"/>
31: <TextBox Grid.Row="0" Grid.Column="1" Text=
32: "{Binding FirstName, UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay}">
33: </TextBox>
34: <TextBlock Text="Your First Name:" Grid.Column="0"
Grid.Row="1"/>
35: <TextBlock Text="{Binding FirstName}" Grid.Column="1"
Grid.Row="1"/ >
36:
37: </Grid>
38: </UserControl>
Ну и код модифицированного класса (чтобы работало связывание в двух направлениях):
1: public class Person: INotifyPropertyChanged
2: {
3: public string firstName;
4:
5: public string FirstName {
6: get { return firstName; }
7: set {
8: firstName = value;
9: OnPropertyChanged(new
PropertyChangedEventArgs("FirstName"));
10: }
11: }
12:
13: public event PropertyChangedEventHandler PropertyChanged;
14:
15: public void OnPropertyChanged(PropertyChangedEventArgs e)
16: {
17: if (PropertyChanged != null)
18: PropertyChanged(this, e);
19: }
20:
21: }
В результате, если вводить текст в поле редактирования, он тут же будет отображаться и в поле ниже. Это не всегда хорошо, так как если текст проходит валидацию, то в процессе набора нет необходимости требовать его корректность, но иногда такая возможность может быть полезна.
Теперь в стилях также можно применять связывание. Это упрощает "натягивание" уникальной оболочки для каждого пользователя, позволяя загружать стили динамически, а также предусматривать установку и модификацию характеристик интерфейса.
1: <Grid.Resources >
2: <Style TargetType="TextBox">
3: <Setter Property="Background" Value="{Binding background}"/>
4: <Setter Property="Width" Value="{Binding width}"></Setter>
5: <Setter Property="Margin" Value="{Binding margin}"></Setter>
6: </Style>
7: <Style TargetType="TextBlock">
8: <Setter Property="Margin" Value="{Binding margin}"></Setter>
9: </Style>
10: </Grid.Resources>
Класс модели
1: public class TextStyle
2: {
3: public string width { get; set; }
4: public string background { get; set; }
5: public string margin { get; set; }
6: }
И связывание:
1: LayoutRoot.DataContext = new TextStyle()
2: { width = "200", background = "Blue", margin = "5" };
Шаблоны данных позволяют указать формат/разметку отображения не интерфейсных данных и использовать эту разметку в различных местах нашего приложения.
Неявные шаблоны позволяют формировать разметку, базируясь на типе данных. В более ранних версиях технологии необходимо было указывать ключ шаблона, чтобы его использовать в нескольких местах приложения. Используя неявные шаблоны, нам необходимо лишь указать, для какого типа данных необходимо использовать шаблон.
Создадим проект и добавим несколько типов данных
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Title { get; set; }
public string Company { get; set; }
}
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Room { get; set; }
}
Добавим несколько шаблонов данных в ресурсы приложения(файл App.xaml)
<Application
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ImplicitDataTemplate.App"
xmlns:data="clr-namespace:ImplicitDataTemplate">
<Application.Resources>
<DataTemplate DataType="data:Customer">
<Grid Background="LightSkyBlue">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName,
StringFormat='\{0\} '}"/>
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
<StackPanel Grid.Row="1">
<TextBlock Text="{Binding Title}" FontStyle="Italic"/>
<TextBlock Text="{Binding Company,
StringFormat='Компания: \{0\}'}" FontWeight="Bold"/>
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate DataType="data:Employee">
<Grid Background="LightGreen" >
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<Grid.RowDefinitions>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right">
<TextBlock Text="{Binding FirstName,
StringFormat='\{0\} '}"/>
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal"
HorizontalAlignment="Right">
<TextBlock Text="{Binding Room,
StringFormat='Комната: \{0\}'}" FontStyle="Italic"/>
</StackPanel>
</Grid>
</DataTemplate>
</Application.Resources>
</Application>
И последний момент, создание тестовых данных в приложении, связывание их с формой
this.DataContext = new List<object>
{
new Customer{ FirstName="Иван", LastName="Копаткинский",
Company="Топинамбур", Title="Бухгалтер"},
new Customer{ FirstName="Дмитрий", LastName="Вирутон",
Company="Пальма туриста", Title="Менеджер"},
new Employee{ FirstName="Павел", LastName="Уловинко", Room=101}
};
и добавление компонента ListBox для отображения списка данных
<Grid x:Name="LayoutRoot" Background="White">
<ListBox ItemsSource="{Binding}"/>
</Grid>
Результат работы:
(рис 7.8) Результат применения неявных шаблонов в Silverlight 5
Для полноты статьи приведем еще несколько нововведений, которые сами по себе интересны, но не стоят отдельного раздела из-за своей прозрачности (понятности).
Особое внимание стоит обратить на новое событие DataContextChanged, которое представлено в базовом классе FrameworkElement. Теперь элемент способен отреагировать на изменение источника данных.
Если связывание происходит с другими элементами в модели, то теперь можно использовать свойство RelativeSource совместно с FindAncestor. Это позволяет указать вместо имени элемента, его тип и уровень вложенности. В результате нужный элемент будет найден в реальном времени и выполнено связывание.
Последнее нововведение, это доступность интерфейса ICustomTypeProvider, описывающего метод GetCustomType. Данный интерфейс может быть полезен, когда Вы создаете объекты с динамически сгенерированными свойствами. В этом случае Вы генерируете и возвращаете объект типа Type, описывающий все свойства, которые Вы хотели бы использовать при связывании. Аналогичным образом можно поступить, когда Вы хотите скрыть некоторые свойства от элементов управления, генерирующих свою структуру автоматически. Например, DataGrid, генерирующий свои колонки автоматически.
Silverlight – новая технология от Mirosoft, предназначенная для разработки насыщенных Web – приложений. Особенности версии Silverlight 4 – интенсивное использование графики, анимации, работа с медиа-файлами, а так же эффективное взаимодействие с данными и серверными компонентами. В декабре 2010 года в Microsoft сообщили, что Silverlight 5 будет включать 40 новых функций. Большая часть которых, также как и в изменениях, пришедших с 4 версией Silverlight, сосредоточена вокруг графики, анимации и работы с медиа-файлами. 1 сентября 2011 Silverlight 5 от Microsoft перешел в стадию
Вопросы:
Цель лекции: показать историю развития платформы Silverlight и дать понимание дальнейшей тенденции. Изложить структуру и возможности Silverlight 4 по разработке интерактивных интернет-приложений нового поколения. Продемонстрировать новые возможности Silverlight 5, реализованные в версии
В настоящее время доступны четыре версии
Silverlight 1. Это выпуск Silverlight не имел общеязыковой среды выполнения. Он поддерживал небольшое подмножество XAML и множество возможностей, которые предвещали будущее Silverlight. Возможно самый очевидный аспект Silverlight 1 – то, что приложения написаны или полностью на XAML или в смеси с JavaScript и объектной моделью документов, чтобы управлять интерфейсом пользователя. Так как нет общеязыковой среды выполнения, нет фазы компиляции, и JavaScript интерпретируется на клиентской стороне.
Silverlight 2. Вскоре после того, как вышел Silverlight 1, был выпущен предварительный релиз следующей версии Silverlight. Этот выпуск был известен как Silverlight 1.1, наиболее значительным аспектом которого является
Silverlight 3. В марте 2009 Microsoft выпустила бета-версию Silverlight 3. В июле 2009 появилась среда разработки Expression Blend 3. Silverlight 3 является расширением Silverlight 2 и главным образом обеспечивает усовершенствование возможностей графики, управления медиа, области разработки приложений (дополнительные элементы управления, усовершенствованная поддержка связывания элементов управления с данными, поддержка внебраузерных приложений), а также интеграцию с Expression Blend.
Silverlight 4. Microsoft главным образом фокусировалась на возможностях, управляемых медиа до версии Silverlight 3. Silverlight 3 представил ключевые возможности
Бета-версия Silverlight 4 была быстро выпущена в ноябре 2009, а окончательный релиз Silverlight 4 появился 12 апреля 2010 во время конференции DevConnection. Детальный разбор архитектуры программной платформы Silverlight 4 был приведен во второй лекции.
Silverlight 4 имеет следующие ключевые особенности:
Возможность для приложений Silverlight быть "доверенными" так же, как внебраузерные приложения открывает многие возможности, которые обеспечивают традиционные WPF-приложения, которые могут вызывать "родной" код за пределами "песочницы" на клиентской машине:
Silverlight 4 действительно включает несколько ключевых расширений, чтобы защитить, обработать и доставить более дружественные с медиа
Следующие усовершенствования основной платформы и компонентов помогут улучшить интерфейс конечного пользователя и разрабатывать корпоративные приложения в режиме быстрой разработки.
Рассмотрим ожидаемые возможности релиза.
Даже Silverlight 4 не работает в 64-битных браузерах. Между тем, 32-бита уверенно уходят в прошлое. Именно поэтому, начиная с 5-й версии Silverlight, плагин будет доступен как в 32-битной, так и в 64-битной версиях. Предполагается, что пользователю не придется думать, какая из версий должна быть установлена.
Речь идет о том, что при просмотре видео с помощью Silverlight (а, следовательно, при отсутствии взаимодействия с мышью и клавиатурой), Вас не застанет врасплох установленный на машине
В Silverlight 4 появился класс
Речь идет не о технологии псевдо 3D, появившейся в Silverlight 4, а о полноценном 3D API с поддержкой аппаратного ускорения. Последнее уже хорошо зарекомендовало себя при работе с видео.
Поддержка Behaviors призвана перенести функциональность Поведений, реализованных в Blend, на уровень ядра Silverlight. Речь идет о создании комплексных объектов, объединяющих в себе ряд различных преобразований, создавая тем самым уникальное Поведение. И если ранее подобное можно было реализовать, только подключив специальную сборку из Blend, то теперь это все будет в ядре. Введение триггеров призвано еще больше сблизить WPF и Silverlight, хотя триггеры в Silverlight выглядят более универсальными.
В Silverlight 5 любому контейнеру будет можно задавать эффекты, связанные с заполнением контейнера и добавлением нового элемента. Благодаря Layout transition разработчику не придется работать с каждым элементом отдельно, а достаточно будет указать механизм заполнения для всего контейнера.
У разработчиков теперь будет меньше головной боли, так как появилась возможность ставить точки останова в коде, описывающем связывание данных. Достаточно поставить точку останова в XAML файле, на строке, описывающей Binding, и разработчик может получить всю возможную информацию о связывании и проблемах, возникающих с этим. Поэтому найти такие ошибки, как неправильное написание имени свойства или имени преобразователя типов, станет теперь проще.
FindAncestor позволяет выполнять связку, выполняя поиск любого вышестоящего элемента, и выполнять с ним связывание.
Как видно, Silverlight 5 все ближе и ближе приближается к WPF. Новое событие DataContextChanged позволит определить изменение источника данных при связывании.
Связывание теперь можно будет использовать в
Silverlight 5 будет поддерживать правила, установленные групповыми политиками. Поддержка групповых политик позволит централизовано управлять развертыванием Silverlight-приложений. Кроме того, это даст возможность устанавливать список Publishers, разрешая избранным приложениям работать внутри браузера, но с использованием Full-Trust со всеми вытекающими последствиями (включая поддержку элемента WebBrowser). Это нововведение связано с отзывом от некоторых компаний, которые хотят запускать свои корпоративные приложения внутри браузера, но с повышенными привилегиями.
Обычно требуется реализовать обработчик события при двойном щелчке, но Silverlight позволяет обрабатывать и большее количество нажатий. Речь идет как о левой, так и о правой кнопках мыши. Тут разработчики немного схитрили. Чтобы не менять модель событий и не вводить новые события на двойной щелчок мыши, к параметру EventArgs уже существующих событий, возникающих при однократном нажатии кнопки мыши, было добавлено свойство ClickCount. Это свойство и содержит количество нажатий.
Интересно то, что события MouseLeftButtonDown и MouseRightButtonDown срабатывают для каждого щелчка, даже если вы хотите обрабатывать только двойной щелчок. При этом, если между щелчками проходит больше секунды, или другое событие (например, пользователь еще и потянул мышь), то счетчик обнуляется. Поэтому, если Вы хотите для одного и того же объекта обрабатывать одинарный и двойной (а может и тройной) щелчок, то необходимо, чтобы они не были взаимоисключающими. Иными словами, при одинарном щелчке Вы можете выбрать папку, а при двойном – открыть папку. Наоборот работать не будет, так как уже при первом щелчке папка будет открыта.
Ниже показан простой код, который позволяет отобразить количество щелчков:
<Grid x:Name="LayoutRoot" Background="White"
MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown">
<sdk:Label Height="28" HorizontalAlignment="Left"
Name="label1" VerticalAlignment="Top" Width="120" />
</Grid>
Данный функционал достаточно простой, но приятный. Вспомните бесконечные элементы ComboBox со списком стран, или элементы, позволяющие установить фильтр по чьей-то фамилии, выбрав ее из сотни других и т. д. Для всех этих случаев, имея элемент-наследник от ItemsControl, такой как ListBox, ComboBox и другие, Вы всегда должны были пользоваться скроллингом, чтобы найти нужный элемент (это утверждение относится к Silverlight). В WPF или даже в простом HTML, подобные элементы давно поддерживают возможность выбора с клавиатуры. Так, переходя на тот же выпадающий список стран, мне достаточно легко набрать на клавиатуре букву "Р", чтобы увидеть активным элементом слово "Россия". Это позволяет быстро заполнять сложные формы с большим количеством опций. Теперь такая возможность появилась и в Silverlight. Рассмотрим простой пример:
<Grid x:Name="LayoutRoot" Background="White">
<ComboBox Height="23" HorizontalAlignment="Left"
Name="comboBox1" VerticalAlignment="Top" Width="120">
<ComboBoxItem Content="Последний" />
<ComboBoxItem Content="Третий" />
<ComboBoxItem Content="Второй" />
<ComboBoxItem Content="Первый" />
</ComboBox>
</Grid>
На экране отобразится обычный ComboBox, который позволяет выбрать один из четырех элементов. Переключитесь на русскую клавиатуру и попробуйте понажимать символ "П". ComboBox будет последовательно выбирать один из двух элементов (Первый и Последний). Если Вы последовательно наберете два символа, например "Пе", то будет выбран "Первый" без альтернатив.
Понятно, что ComboBox в Silverlight, как и другие ItemsControl, позволяет отображать что угодно и не обязательно текст, особенно если речь идет о связывании со сложными объектами. Именно поэтому, для всех элементов ItemsControl ввели дополнительное свойство TextPath, которое задает имя свойства объекта, с которым мы реализуем связывание, используемое при выборе элемента с клавиатуры.
<ComboBox Height="23" TextSearch.TextPath="ImageTitle"
HorizontalAlignment="Left" Name="comboBox1"
VerticalAlignment="Top" Width="120">
В предыдущих версиях Silverlight, приложения, которые получали возможность работать вне браузера, могли претендовать на дополнительные (повышенные) привилегии. Это позволяло подобным приложениям получать доступ к диску, расширять изолированное хранилище без уведомления пользователя, реализовывать доступ к клавиатуре в полноэкранном режиме и многое другое. Между тем, многие разработчики желали бы иметь подобную функциональность и для приложений, работающих в браузере. Естественно речь идет о корпоративных приложениях, которые доступны только сотрудникам филиалов и при этом могут часто обновляться. В связи с этим в Silverlight 5 появилась возможность создавать приложения с повышенными полномочиями, работающими в окне браузера. Рассмотрим процедуру создания таких приложений.
Приложение необходимо подписать сертификатом, что вполне можно сделать из оболочки Visual Studio в настройках проекта (рис. 7.1).
(рис 7.1) Вкладка Signing
Тут вы можете сгенерировать тестовый сертификат или выбрать его из хранилища (файла). Теоретически, если вы создаете приложение для работы внутри своей сети, сертификат можно и не покупать, а пользоваться тестовым.
Далее необходимо развернуть сертификат на машинах, где будет работать ваше Silverlight-приложение. Если вы хотите протестировать функциональность на рабочей машине, то это можно легко сделать, нажав кнопку More Details… в диалоге выше, перейдя к параметрам сертификата (рис. 7.2):
(рис 7.2) Вкладка General
На следующем этапе нужно у всех клиентов разрешить запуск приложений в браузере с повышенными полномочиями. Это можно сделать, установив значение AllowElevatedTrustAppsInBrowser (DWORD) в 0х00000000 (disabled) или 0?00000001 (enabled) в ключах HKEY_LOCAL_MACHINE\Software\Microsoft\Silverlight\ (для 32 бит) или HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Silverlight\ (для 64 бит).
Необходимо внести изменения в конфигурационный файл таким образом, чтобы ваше приложение при работе с браузером запрашивало дополнительные полномочия. Это легко можно сделать в настройках проекта, выбрав соответствующую галочку (рис. 7.3):
(рис 7.3) Вкладка Silverlight
После этих действий, Visual Studio сгенерирует дополнительный конфигурационный файл следующего содержимого:
<InBrowserSettings>
<InBrowserSettings.SecuritySettings>
<SecuritySettings ElevatedPermissions="Required" />
</InBrowserSettings.SecuritySettings>
</InBrowserSettings>
Теперь ваши приложения (подписанные сертификатом), будут запускаться в браузере с дополнительными полномочиями, включая полную поддержку клавиатуры в полноэкранном режиме, поддержку элементов WebBrowser и NotificationWindow и др.
Хочется отметить, что если вы попробуете тестировать эту процедуру, запуская приложение через localhost, то первые три шага игнорируются. Поэтому не попадите в заблуждение: если на вашей машине работает, то будет работать и на других.
Для приложений с повышенными привилегиями, работающих вне браузера, стало возможным отображать несколько немодальных окон, которые могут перемещаться за пределы родительского окна, а также интегрируются с панелью задач Windows 7.
Ниже приведен небольшой код, который, внутри конструктора главного окна, генерирует дочернее окно и делает его видимым:
public MainPage()
{
InitializeComponent();
Window childWindow = new Window();
childWindow.Height = 400;
childWindow.Width = 600;
childWindow.Top = 30;
childWindow.Left = 30;
childWindow.Title = "Child Window";
childWindow.Visibility = Visibility.Visible;
}
В данном примере дочернее окно создается с размерами 600 на 400, при этом верхний левый его угол будет находиться в позиции (30, 30), относительно экрана системы (не родительского окна). При этом обратите внимание на то, что созданное окно поддерживается панелью задач Windows 7 (рис. 7.4):
(рис 7.4) Поддержка нескольких окон в Silverlight 5
Технология Silverlight 4 поддерживала возможность приложениям с повышенными привилегиями получать доступ к файловой системе пользователя. Правда, доступ был ограничен лишь несколькими папками. Так, в режиме с повышенными привилегиями, приложения получают полный контроль к специальным папкам, ассоциированным с пользователем: MyDocuments, MyVideos, MyPictures, MyMusic. Пути к указанным папкам можно получить, используя статический класс Environment. При этом нужно отметить, что SilverLight-приложение работает только с папками, но не с библиотеками (Windows 7).
В Silverlight 5 появилась возможность взаимодействовать со всей файловой системой пользователя. Речь идет как о чтении файлов, так и о записи.
Теперь при вызове этого диалогового окна, можно установить имя файла (как и список расширений), которое будет отображаться по умолчанию, как имя файла, предлагаемого для записи. Вот как это выглядит:
SaveFileDialog dialog = new SaveFileDialog(); dialog.DefaultFileName = "hello.txt"; dialog.ShowDialog();
Кроме описанной возможности, появилось свойство InitialDirectory, позволяющее задать директорию, которая будет открыта в диалоге по умолчанию.
В Silverlight 5 стала доступна библиотека по работе с Media. Классы этой библиотеки представлены пространством имен Microsoft.Xna.Framework.Audio. Нетрудно догадаться, что данный шаг выполнен в рамках интеграции с XNA библиотеками, которые можно использовать и в Silverlight (это аудио и 3D).
Новое пространство имен содержит два основных класса, позволяющих создавать аудио эффекты в процессе работы Silverlight приложения. Файлы, доступные для проигрывания, должны быть в формате WAV и могут быть загружены с помощью класса SoundEffect. Конструктор этого класса получает ссылку на набор данных и (или) настройки аудио. Создание конкретного экземпляра можно также выполнить с помощью статического метода FromStream, получающего ссылку на поток в качестве параметров. Проигрывание эффекта осуществляется с помощью метода Play. Каких-то других методов SoundEffect не имеет, но это вовсе не означает, что отдельно взятым объектом нельзя управлять. Так, если вы хотите не просто воспроизвести эффект, но и добавить элементы управления аудио (громкость, пауза и т .д.), то вместо метода Play следует вызывать метод CreateInstance, создающий конкретный экземпляр на базе SoundEffect, и возвращающий ссылку типа SoundEffectInstance, которая позволит управлять нашим аудио файлом.
SoundEffect sEffect=SoundEffect.FromStream(streamInfo.Stream); sEffect.Play();
В Silverlight 5 произошли улучшения и в MediaElement элементе. Теперь этот элемент управления содержит такое свойство как PlaybackRate и событие RateChanged. Свойство позволяет задавать скорость проигрывания, синхронизировать видео и звук, а также выполнять "переметку" не только вперед, но и назад. Предполагается, что можно будет использовать следующие множители для скорости проигрывания: 0.2, 0.4, 0.6, 0.8, 1, 2, 4, 8, 16, 32. Событие RateChanged позволит реагировать на изменение свойства.
Silverlight 5 поддерживает и работу с пультом. Данная функциональность стала доступна благодаря поддержке события MediaCommand, которое доступно у всех UIElement. Иными словами, если вы хотите обрабатывать нажатия кнопок пульта, то Вам следует обработать это событие у родительского контейнера (от дочерних элементов оно как раз туда и свалится). Чтобы понять, какая кнопка на пульте была нажата, обработчик события получает доступ к свойству в MediaCommandEventArgs, содержащему свойство MediaCommand. Последнее и содержит информацию по нажатой кнопке.
Silverlight 5 предлагает несколько интересных возможностей при работе с текстом. Так, элементы управления Control, TextBlock и TextElement, имеют новое свойство CharacterSpacing. Это свойство позволяет установить расстояние между символами внутри текста.
Свойство LineHeight позволяет установить ширину строки (можно интерпретировать, как расстояние между строками) и определено в таких элементах как Block, TextBlock, TextBox и RichTextBox. Для элемента RichTextBox можно также задать стратегию с помощью свойства LineStackingStrategy. На рис. 7.5 пример текста внутри элемента TextBlock с расстоянием между строками 30 и расстоянием между символами – 200:
(рис 7.5) Пример возможности TextBlock в Silverlight 5
Наконец, Silverlight 5 стал поддерживать два новых текстовых элемента, это RichTextBlock и RichTextBlockOverflow. Эти элементы аналогичны элементам RichTextBox и RichTextBoxOverflow, но позволяют отображать текст только на чтение.
Рассмотрим небольшой пример с элементом RichTextBlockOverflow:
<StackPanel x:Name="LayoutRoot" Background="White"
Orientation="Horizontal" VerticalAlignment="Top">
<RichTextBlock
Width="250" FontSize="16" OverflowContentTarget=
"{Binding ElementName=SecondBox}">
<Paragraph>
В лесу родилась елочка,
</Paragraph>
. . . . . . . . //повторить 20 разJ
</RichTextBlock>
<RichTextBlockOverflow Width="250" Name="SecondBox">
</RichTextBlockOverflow>
</StackPanel>
Результат работы этого кода показан на рис. 7.6:
(рис 7.6) Пример с элементом RichTextBlockOverflow в Silverlight 5
Как видно, RichTextBlockOverflow может отображать текст, который не "вмещается" в основной элемент RichTextBlock. Благодаря таким элементам мы можем размещать текст в 2, 3 и более колонках (или реализовывать более сложные сценарии).
Silverlight 5 позволяет теперь не только реализовать растровую, но и векторную печать. Для этих целей используется все тот же метод Print класса PrintDocument, который осуществляет попытку печати в векторном формате, а в случае неудачи (принтер не поддерживает), перейти к печати в растровом виде. Растровую печать можно инициировать с помощью нового метода PrintBitmap.
В документации эта возможность пока не описана, но она уже реализована – возможность вызова методов Windows API из Silverlight приложений, обладающих повышенными полномочиями. Причем речь идет о приложениях, которые работают как в браузере, так и вне браузера. Поскольку вызов нативных функций в .NET обычно осуществляется с помощью атрибута DllImport. Запустим приложение с повышенными привилегиями:
public partial class MainPage : UserControl
{
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd,
String text, String caption, uint type);
public MainPage()
{
MessageBox(new IntPtr(0), "Hello World!", "Hello Dialog", 0);
InitializeComponent();
}
}
На экране поверх браузера вы увидите стандартный MessageBox.
Современный отладчик в Visual Studio давно позволяет разработчику получать всю необходимую информацию, если речь идет о коде на C#, C++ или даже JavaScript. Но как только речь заходит о XAML, то тут механизмы отсутствуют. Казалось бы, зачем нужна отладка в XAML, если тут идет декларативное описание интерфейса приложения. Действительно, отладка в XAML не нужна, если речь не идет о связывании с данными. Небольшой кусок кода, связывающий наши данные и интерфейс, может вызвать массу проблем при отладке. Ведь причин для возникновения проблем при связывании может быть множество, это и отсутствие какого-либо свойства, и проблемы с преобразованием либо же
Рассмотрим небольшой пример кода на XAML:
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
xmlns:d=http://schemas.microsoft.com/expression/blend/2008
xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006
Loaded="UserControl_Loaded"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.Resources>
<Style TargetType="TextBox">
<Setter Property="Background" Value="AliceBlue"></Setter>
<Setter Property="Width" Value="200"></Setter>
<Setter Property="Margin" Value="5"></Setter>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="5"></Setter>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="First Name:" Grid.Column="0" Grid.Row="0"/>
<TextBlock Text="First Name:" Grid.Column="0" Grid.Row="1"/>
<TextBlock Text="First Name:" Grid.Column="0" Grid.Row="2"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding FisrtName}"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding LastName}"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Age}"/>
</Grid>
</UserControl>
В результате мы получим небольшую формочку, которая позволяет заполнить три поля. Код, необходимый для работы формы, может выглядеть так:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Person p = new Person();
p.FirstName = "Sergey";
p.LastName="Baydachnyy";
p.Age = 33;
LayoutRoot.DataContext = p;
}
И класс Person:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
Запустив это приложение, можно убедиться, что первое поле не было заполнено данными. Чтобы понять причину ошибки, достаточно установить Breakpoint в XAML файле на строку, описывающую связывание в первом поле, и запустить приложение в режиме отладки. Вот что можно увидеть в окне Locals:
(рис 7.7) Отладка XAML в Silverlight 5
Тут и информация об ошибке (ошибка намеренно сделана в имени поля) и данные об объекте и т. д. То есть, сгенерированный объект BindingState четко позволяет выявить проблему и проверить правильность данных.
Данная поддержка состоит в расширении TextBox, то в случае двунаправленного связывания, при изменении элемента TextBox, источник мог быть обновлен лишь при потере фокуса или явным образом. Значение PropertyChanged позволяет реагировать на любые изменения в текстовом поле "на лету". При этом нет необходимости обрабатывать нажатия клавиш и т .д. Вот пример кода:
1: <UserControl x:Class="SilverlightApplication1.MainPage"
2: xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
3: xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
4: xmlns:d=http://schemas.microsoft.com/expression/blend/2008
5: xmlns:mc=http://schemas.openxmlformats.org/markup-ompatibility/2006
6: Loaded="UserControl_Loaded"
7: mc:Ignorable="d"
8: d:DesignHeight="300" d:DesignWidth="400">
9:
10: <Grid x:Name="LayoutRoot" Background="White">
11: <Grid.Resources>
12: <Style TargetType="TextBox">
13: <Setter Property="Background" Value="AliceBlue"/>
14: <Setter Property="Width" Value="200"/>
15: <Setter Property="Margin" Value="5"/>
16: </Style>
17: <Style TargetType="TextBlock">
18: <Setter Property="Margin" Value="5"/>
19: </Style>
20: </Grid.Resources>
21: <Grid.RowDefinitions>
22: <RowDefinition Height="Auto"></RowDefinition>
23: <RowDefinition Height="Auto"></RowDefinition>
24: </Grid.RowDefinitions>
25: <Grid.ColumnDefinitions>
26: <ColumnDefinition Width="Auto"></ColumnDefinition>
27: <ColumnDefinition Width="Auto"></ColumnDefinition>
28: </Grid.ColumnDefinitions>
29:
30: <TextBlock Text="First Name:" Grid.Column="0" Grid.Row="0"/>
31: <TextBox Grid.Row="0" Grid.Column="1" Text=
32: "{Binding FirstName, UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay}">
33: </TextBox>
34: <TextBlock Text="Your First Name:" Grid.Column="0"
Grid.Row="1"/>
35: <TextBlock Text="{Binding FirstName}" Grid.Column="1"
Grid.Row="1"/ >
36:
37: </Grid>
38: </UserControl>
Ну и код модифицированного класса (чтобы работало связывание в двух направлениях):
1: public class Person: INotifyPropertyChanged
2: {
3: public string firstName;
4:
5: public string FirstName {
6: get { return firstName; }
7: set {
8: firstName = value;
9: OnPropertyChanged(new
PropertyChangedEventArgs("FirstName"));
10: }
11: }
12:
13: public event PropertyChangedEventHandler PropertyChanged;
14:
15: public void OnPropertyChanged(PropertyChangedEventArgs e)
16: {
17: if (PropertyChanged != null)
18: PropertyChanged(this, e);
19: }
20:
21: }
В результате, если вводить текст в поле редактирования, он тут же будет отображаться и в поле ниже. Это не всегда хорошо, так как если текст проходит валидацию, то в процессе набора нет необходимости требовать его корректность, но иногда такая возможность может быть полезна.
Теперь в стилях также можно применять связывание. Это упрощает "натягивание" уникальной оболочки для каждого пользователя, позволяя загружать стили динамически, а также предусматривать установку и модификацию характеристик интерфейса.
1: <Grid.Resources >
2: <Style TargetType="TextBox">
3: <Setter Property="Background" Value="{Binding background}"/>
4: <Setter Property="Width" Value="{Binding width}"></Setter>
5: <Setter Property="Margin" Value="{Binding margin}"></Setter>
6: </Style>
7: <Style TargetType="TextBlock">
8: <Setter Property="Margin" Value="{Binding margin}"></Setter>
9: </Style>
10: </Grid.Resources>
Класс модели
1: public class TextStyle
2: {
3: public string width { get; set; }
4: public string background { get; set; }
5: public string margin { get; set; }
6: }
И связывание:
1: LayoutRoot.DataContext = new TextStyle()
2: { width = "200", background = "Blue", margin = "5" };
Шаблоны данных позволяют указать формат/разметку отображения не интерфейсных данных и использовать эту разметку в различных местах нашего приложения.
Неявные шаблоны позволяют формировать разметку, базируясь на типе данных. В более ранних версиях технологии необходимо было указывать ключ шаблона, чтобы его использовать в нескольких местах приложения. Используя неявные шаблоны, нам необходимо лишь указать, для какого типа данных необходимо использовать шаблон.
Создадим проект и добавим несколько типов данных
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Title { get; set; }
public string Company { get; set; }
}
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Room { get; set; }
}
Добавим несколько шаблонов данных в ресурсы приложения(файл App.xaml)
<Application
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ImplicitDataTemplate.App"
xmlns:data="clr-namespace:ImplicitDataTemplate">
<Application.Resources>
<DataTemplate DataType="data:Customer">
<Grid Background="LightSkyBlue">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName,
StringFormat='\{0\} '}"/>
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
<StackPanel Grid.Row="1">
<TextBlock Text="{Binding Title}" FontStyle="Italic"/>
<TextBlock Text="{Binding Company,
StringFormat='Компания: \{0\}'}" FontWeight="Bold"/>
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate DataType="data:Employee">
<Grid Background="LightGreen" >
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<Grid.RowDefinitions>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right">
<TextBlock Text="{Binding FirstName,
StringFormat='\{0\} '}"/>
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal"
HorizontalAlignment="Right">
<TextBlock Text="{Binding Room,
StringFormat='Комната: \{0\}'}" FontStyle="Italic"/>
</StackPanel>
</Grid>
</DataTemplate>
</Application.Resources>
</Application>
И последний момент, создание тестовых данных в приложении, связывание их с формой
this.DataContext = new List<object>
{
new Customer{ FirstName="Иван", LastName="Копаткинский",
Company="Топинамбур", Title="Бухгалтер"},
new Customer{ FirstName="Дмитрий", LastName="Вирутон",
Company="Пальма туриста", Title="Менеджер"},
new Employee{ FirstName="Павел", LastName="Уловинко", Room=101}
};
и добавление компонента ListBox для отображения списка данных
<Grid x:Name="LayoutRoot" Background="White">
<ListBox ItemsSource="{Binding}"/>
</Grid>
Результат работы:
(рис 7.8) Результат применения неявных шаблонов в Silverlight 5
Для полноты статьи приведем еще несколько нововведений, которые сами по себе интересны, но не стоят отдельного раздела из-за своей прозрачности (понятности).
Особое внимание стоит обратить на новое событие DataContextChanged, которое представлено в базовом классе FrameworkElement. Теперь элемент способен отреагировать на изменение источника данных.
Если связывание происходит с другими элементами в модели, то теперь можно использовать свойство RelativeSource совместно с FindAncestor. Это позволяет указать вместо имени элемента, его тип и уровень вложенности. В результате нужный элемент будет найден в реальном времени и выполнено связывание.
Последнее нововведение, это доступность интерфейса ICustomTypeProvider, описывающего метод GetCustomType. Данный интерфейс может быть полезен, когда Вы создаете объекты с динамически сгенерированными свойствами. В этом случае Вы генерируете и возвращаете объект типа Type, описывающий все свойства, которые Вы хотели бы использовать при связывании. Аналогичным образом можно поступить, когда Вы хотите скрыть некоторые свойства от элементов управления, генерирующих свою структуру автоматически. Например, DataGrid, генерирующий свои колонки автоматически.
Silverlight – новая технология от Mirosoft, предназначенная для разработки насыщенных Web – приложений. Особенности версии Silverlight 4 – интенсивное использование графики, анимации, работа с медиа-файлами, а так же эффективное взаимодействие с данными и серверными компонентами. В декабре 2010 года в Microsoft сообщили, что Silverlight 5 будет включать 40 новых функций. Большая часть которых, также как и в изменениях, пришедших с 4 версией Silverlight, сосредоточена вокруг графики, анимации и работы с медиа-файлами. 1 сентября 2011 Silverlight 5 от Microsoft перешел в стадию
Вопросы:
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.