Методология синхронной разработки приложения в Microsoft Visual Studio 2010

Silverlight и WPF в Visual Studio 2010 (продолжение)

Разбить на страницы
Показывать лекцию целиком

Цель лекции: показать историю развития платформы Silverlight и дать понимание дальнейшей тенденции. Изложить структуру и возможности Silverlight 4 по разработке интерактивных интернет-приложений нового поколения. Продемонстрировать новые возможности Silverlight 5, реализованные в версии Release Candidate.

Новые возможности Silverlight 4. Silverlight 5: основные нововведения ожидаемого релиза

Хронология Silverlight

В настоящее время доступны четыре версии Microsoft Silverlight: Silverlight 1, Silverlight 2, Silverlight 3, и Silverlight 4.

Silverlight 1. Это выпуск Silverlight не имел общеязыковой среды выполнения. Он поддерживал небольшое подмножество XAML и множество возможностей, которые предвещали будущее Silverlight. Возможно самый очевидный аспект Silverlight 1 – то, что приложения написаны или полностью на XAML или в смеси с JavaScript и объектной моделью документов, чтобы управлять интерфейсом пользователя. Так как нет общеязыковой среды выполнения, нет фазы компиляции, и JavaScript интерпретируется на клиентской стороне.

Silverlight 2. Вскоре после того, как вышел Silverlight 1, был выпущен предварительный релиз следующей версии Silverlight. Этот выпуск был известен как Silverlight 1.1, наиболее значительным аспектом которого является кроссплатформенная общеязыковая среда выполнения. Хотя Silverlight 1 мог использоваться, чтобы разработать некоторые впечатляющие и "богатые" медиа-приложения, его возможности значительно расширялись со способностью выполняться на платформе .NET. Самая большая недостающая возможность Silverlight 1.1 – это недостаточный набор стандартных элементов управления. Это делало разработку пользовательских интерфейсов трудной. Обработка входных событий была также трудной, так как события могли перехватываться только в корневом контейнере. Затем вручную приходилось распространять события к дочерним объектам. Использование фокуса ввода было также запутанным. В марте 2008 Microsoft объявила, что Silverlight 1.1 будет фактически выпущен как Silverlight 2, так как набор его возможностей значительно расширился.

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.

Бета-версия Silverlight 4 была быстро выпущена в ноябре 2009, а окончательный релиз Silverlight 4 появился 12 апреля 2010 во время конференции DevConnection. Детальный разбор архитектуры программной платформы Silverlight 4 был приведен во второй лекции.

Silverlight 4 имеет следующие ключевые особенности:

  • Возможность печати контента с использованием нового API печати, позволяет разработчикам создавать пользовательские визуальные представления печати, которые могут быть интегрированы с локальными принтерами или могут быть сохранены как файлы (XPS, PDF).
  • Поддержка контекстных меню является возможностью по умолчанию, обеспечивая интерфейс пользователя, подобный имеющемуся в настольных приложениях.
  • Поддержка Drag and Drop и операций с буфером обмена допускают интеграции локальных файлов или данные с RIA Silverlight.
  • Новые элементы управления, такие как RichTextBox, который позволяет разработчикам предоставлять область редактирования текста с поддержкой текстового форматирования, гиперссылок и изображений в приложениях Silverlight. Новые элементы управления WebBrowser и WebBrowser-Brush позволяют интегрировать HTML-контент в приложения, которые являются внебраузерными.
  • Расширение возможностей существующих элементов управления, таких как DataGrid поддержкой сортировки и изменения размеров, а также операций с буфером обмена.
  • Улучшенная привязка к данным
  • Улучшенные возможности локализации добавляют поддержку для двунаправленного текста, языков, на которых пишут справа-налево и дополнительных 30 новых языков.
  • Введение окон уведомлений для обеспечения основанных на панели задач традиционных уведомлений на клиентской машине, улучшит интерфейс конечного пользователя, обеспечивая непротиворечивый подход, как многие другие традиционные приложения.
  • Поддержка клавиатурного доступа в полноэкранном режиме и простой реализации поддержки колесика мыши обеспечивает обработку события MouseWheel и соответственно значительное улучшение удобства и простоты использования приложений.
  • Возможность интеграции с Web-камерой и микрофоном позволяет разрабатывать интерактивные корпоративные и клиентские приложения, которые поддерживают голосовое взаимодействие и проведение видео-конференций.
  • Возможность для приложений Silverlight быть "доверенными" так же, как внебраузерные приложения открывает многие возможности, которые обеспечивают традиционные WPF-приложения, которые могут вызывать "родной" код за пределами "песочницы" на клиентской машине:

  • Поддержка позднего связывания с объектами, полученными от HTML DOM или от Automation API. Это обеспечивает возможность интеграции с COM-приложениями, такими как приложения Microsoft Office (например, Word, Excel, и Outlook) на Windows-клиентах и интеграцию других подключенных устройств.
  • Доступ к Папкам "Мои…" из приложения позволяет доступ ко всем папкам "Мои документы", "Мои видеозаписи", "Изображения", и "Музыка" для Windows и Mac и читать и записывать файлы из приложения, работающего в среде "песочницы".
  • Легкое развертывание и управление, избавляющее от необходимости использования междоменных файлов политик доступа (ClientAccess.xml или CrossDomainAcess.xml), а также возможность создания групповых политик для управления доверенными приложениями.
  • Silverlight 4 действительно включает несколько ключевых расширений, чтобы защитить, обработать и доставить более дружественные с медиа RIA:

  • Поддержка офлайнового управления цифровыми правами поможет доставить медиа в офлайновом режиме в более защищенной и управляемой среде.
  • Возможности интеграции с Web-камерой и микрофоном и возможность записи аудио и видео клиентской стороны, обеспечивают многочисленные возможности для разработки интерактивных аудио/видео RIA.
  • Следующие усовершенствования основной платформы и компонентов помогут улучшить интерфейс конечного пользователя и разрабатывать корпоративные приложения в режиме быстрой разработки.

  • Официальная поддержка web-браузера Google Chrome - это, вероятно, конечный шаг к провозглашению Silverlight кроссбраузерной платформой и, конечно, осчастливит фанатов Google.
  • Введение поддержки широковещательного сетевого взаимодействия по протоколу UDP поможет улучшить потребительские свойства и стабильность приложений, более эффективно используя сетевые ресурсы.
  • WCF-службы RIA помогают разрабатывать многозвенные приложения в режиме быстрой разработки.
  • Полная оптимизация производительности улучшает производительность запуска и выполнения приложений Silverlight 4 по сравнению с приложениями Silverlight 3.
  • Visual Studio 2010 позволяет разработку пользовательского интерфейса для приложений Silverlight 4 (и Silverlight 3) и вводит улучшенную привязку данных и интеграцию WCF-служб RIA, а также другие расширения, чтобы улучшить опыт разработки.
  • Silverlight 4 и инструментальные средства разработки Windows Phone допускают разработку интерактивных приложений Silverlight для мобильного телефонов серии Windows 7. Вы можете разрабатывать высококачественные медиа-приложения (включая интеграцию с видео камерой и микрофоном) для игровых приложений для мобильных телефонов Windows.
  • Обзор Silverlight 5

    Рассмотрим ожидаемые возможности релиза.

    Поддержка 64-битной платформы

    Даже Silverlight 4 не работает в 64-битных браузерах. Между тем, 32-бита уверенно уходят в прошлое. Именно поэтому, начиная с 5-й версии Silverlight, плагин будет доступен как в 32-битной, так и в 64-битной версиях. Предполагается, что пользователю не придется думать, какая из версий должна быть установлена.

    Улучшенное управление питанием

    Речь идет о том, что при просмотре видео с помощью Silverlight (а, следовательно, при отсутствии взаимодействия с мышью и клавиатурой), Вас не застанет врасплох установленный на машине Screensaver и Вам не придется бросаться к мыши, чтобы продолжить смотреть видео.

    Копирование изображений

    В Silverlight 4 появился класс Clipboard, который позволил копировать текст в буфер и обратно. Silverlight 5 расширяет возможности этого класса, позволяя работать с изображениями. Методы SetImage и GetImage будут работать с объектами типа BitmapSource. Также предусмотрено наличие метода ContainsImage, проверяющего наличие изображения в буфере.

    Поддержка 3D

    Речь идет не о технологии псевдо 3D, появившейся в Silverlight 4, а о полноценном 3D API с поддержкой аппаратного ускорения. Последнее уже хорошо зарекомендовало себя при работе с видео.

    Поддержка Behaviors и Triggers

    Поддержка Behaviors призвана перенести функциональность Поведений, реализованных в Blend, на уровень ядра Silverlight. Речь идет о создании комплексных объектов, объединяющих в себе ряд различных преобразований, создавая тем самым уникальное Поведение. И если ранее подобное можно было реализовать, только подключив специальную сборку из Blend, то теперь это все будет в ядре. Введение триггеров призвано еще больше сблизить WPF и Silverlight, хотя триггеры в Silverlight выглядят более универсальными.

    Layout transition

    В Silverlight 5 любому контейнеру будет можно задавать эффекты, связанные с заполнением контейнера и добавлением нового элемента. Благодаря Layout transition разработчику не придется работать с каждым элементом отдельно, а достаточно будет указать механизм заполнения для всего контейнера.

    Связывание с данными

    Отладка

    У разработчиков теперь будет меньше головной боли, так как появилась возможность ставить точки останова в коде, описывающем связывание данных. Достаточно поставить точку останова в XAML файле, на строке, описывающей Binding, и разработчик может получить всю возможную информацию о связывании и проблемах, возникающих с этим. Поэтому найти такие ошибки, как неправильное написание имени свойства или имени преобразователя типов, станет теперь проще.

    FindAncestor

    FindAncestor позволяет выполнять связку, выполняя поиск любого вышестоящего элемента, и выполнять с ним связывание.

    DataContextChanged

    Как видно, Silverlight 5 все ближе и ближе приближается к WPF. Новое событие DataContextChanged позволит определить изменение источника данных при связывании.

    Стили

    Связывание теперь можно будет использовать в Setter элементах стилей. Это позволит быстро менять внешний вид окна, задавая различные темы.

    Поддержка Full-Trust внутри браузера

    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>

    Поддержка выбора элементов в ItemsControl с клавиатуры

    Данный функционал достаточно простой, но приятный. Вспомните бесконечные элементы 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 появилась возможность создавать приложения с повышенными полномочиями, работающими в окне браузера. Рассмотрим процедуру создания таких приложений.

    Шаг 1.

    Приложение необходимо подписать сертификатом, что вполне можно сделать из оболочки Visual Studio в настройках проекта (рис. 7.1).

    (рис 7.1) Вкладка Signing

    Тут вы можете сгенерировать тестовый сертификат или выбрать его из хранилища (файла). Теоретически, если вы создаете приложение для работы внутри своей сети, сертификат можно и не покупать, а пользоваться тестовым.

    Шаг 2.

    Далее необходимо развернуть сертификат на машинах, где будет работать ваше Silverlight-приложение. Если вы хотите протестировать функциональность на рабочей машине, то это можно легко сделать, нажав кнопку More Details… в диалоге выше, перейдя к параметрам сертификата (рис. 7.2):

    (рис 7.2) Вкладка General

    Шаг 3

    На следующем этапе нужно у всех клиентов разрешить запуск приложений в браузере с повышенными полномочиями. Это можно сделать, установив значение AllowElevatedTrustAppsInBrowser (DWORD) в 0х00000000 (disabled) или 0?00000001 (enabled) в ключах HKEY_LOCAL_MACHINE\Software\Microsoft\Silverlight\ (для 32 бит) или HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Silverlight\ (для 64 бит).

    Шаг 4

    Необходимо внести изменения в конфигурационный файл таким образом, чтобы ваше приложение при работе с браузером запрашивало дополнительные полномочия. Это легко можно сделать в настройках проекта, выбрав соответствующую галочку (рис. 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

    Теперь при вызове этого диалогового окна, можно установить имя файла (как и список расширений), которое будет отображаться по умолчанию, как имя файла, предлагаемого для записи. Вот как это выглядит:

    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.

    P/Invoke

    В документации эта возможность пока не описана, но она уже реализована – возможность вызова методов 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, то механизма получить информацию о проблеме не было. В Silverlight 5 возможна отладка 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 четко позволяет выявить проблему и проверить правильность данных.

    Улучшенная поддержка шаблона MVVM

    Данная поддержка состоит в расширении перечислимого типа UpdateSourceTrigger значением PropertyChanged. Данное значение влияет на обновление источника данных, происходящее при обновлении цели (элемента, куда данные выгружаются). Ранее этот тип поддерживал лишь два значения, это LostFocus и Explicit. Иными словами, если Вы связываете данные с элементом управления 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 перешел в стадию Release Candidate. Выход финальной версии технологии по-прежнему намечен на конец 2011 года.

    Набор для практики

    Вопросы:

  • Назовите ключевые особенности Silverlight 4
  • Охарактеризуйте основные нововведения Silverlight 5, связанные с текстом
  • Повышение полномочий для приложений в браузере
  • Поддержка нескольких окон в Silverlight 5
  • Страницы:

    Цель лекции: показать историю развития платформы Silverlight и дать понимание дальнейшей тенденции. Изложить структуру и возможности Silverlight 4 по разработке интерактивных интернет-приложений нового поколения. Продемонстрировать новые возможности Silverlight 5, реализованные в версии Release Candidate.

    Новые возможности Silverlight 4. Silverlight 5: основные нововведения ожидаемого релиза

    Хронология Silverlight

    В настоящее время доступны четыре версии Microsoft Silverlight: Silverlight 1, Silverlight 2, Silverlight 3, и Silverlight 4.

    Silverlight 1. Это выпуск Silverlight не имел общеязыковой среды выполнения. Он поддерживал небольшое подмножество XAML и множество возможностей, которые предвещали будущее Silverlight. Возможно самый очевидный аспект Silverlight 1 – то, что приложения написаны или полностью на XAML или в смеси с JavaScript и объектной моделью документов, чтобы управлять интерфейсом пользователя. Так как нет общеязыковой среды выполнения, нет фазы компиляции, и JavaScript интерпретируется на клиентской стороне.

    Silverlight 2. Вскоре после того, как вышел Silverlight 1, был выпущен предварительный релиз следующей версии Silverlight. Этот выпуск был известен как Silverlight 1.1, наиболее значительным аспектом которого является кроссплатформенная общеязыковая среда выполнения. Хотя Silverlight 1 мог использоваться, чтобы разработать некоторые впечатляющие и "богатые" медиа-приложения, его возможности значительно расширялись со способностью выполняться на платформе .NET. Самая большая недостающая возможность Silverlight 1.1 – это недостаточный набор стандартных элементов управления. Это делало разработку пользовательских интерфейсов трудной. Обработка входных событий была также трудной, так как события могли перехватываться только в корневом контейнере. Затем вручную приходилось распространять события к дочерним объектам. Использование фокуса ввода было также запутанным. В марте 2008 Microsoft объявила, что Silverlight 1.1 будет фактически выпущен как Silverlight 2, так как набор его возможностей значительно расширился.

    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.

    Бета-версия Silverlight 4 была быстро выпущена в ноябре 2009, а окончательный релиз Silverlight 4 появился 12 апреля 2010 во время конференции DevConnection. Детальный разбор архитектуры программной платформы Silverlight 4 был приведен во второй лекции.

    Silverlight 4 имеет следующие ключевые особенности:

  • Возможность печати контента с использованием нового API печати, позволяет разработчикам создавать пользовательские визуальные представления печати, которые могут быть интегрированы с локальными принтерами или могут быть сохранены как файлы (XPS, PDF).
  • Поддержка контекстных меню является возможностью по умолчанию, обеспечивая интерфейс пользователя, подобный имеющемуся в настольных приложениях.
  • Поддержка Drag and Drop и операций с буфером обмена допускают интеграции локальных файлов или данные с RIA Silverlight.
  • Новые элементы управления, такие как RichTextBox, который позволяет разработчикам предоставлять область редактирования текста с поддержкой текстового форматирования, гиперссылок и изображений в приложениях Silverlight. Новые элементы управления WebBrowser и WebBrowser-Brush позволяют интегрировать HTML-контент в приложения, которые являются внебраузерными.
  • Расширение возможностей существующих элементов управления, таких как DataGrid поддержкой сортировки и изменения размеров, а также операций с буфером обмена.
  • Улучшенная привязка к данным
  • Улучшенные возможности локализации добавляют поддержку для двунаправленного текста, языков, на которых пишут справа-налево и дополнительных 30 новых языков.
  • Введение окон уведомлений для обеспечения основанных на панели задач традиционных уведомлений на клиентской машине, улучшит интерфейс конечного пользователя, обеспечивая непротиворечивый подход, как многие другие традиционные приложения.
  • Поддержка клавиатурного доступа в полноэкранном режиме и простой реализации поддержки колесика мыши обеспечивает обработку события MouseWheel и соответственно значительное улучшение удобства и простоты использования приложений.
  • Возможность интеграции с Web-камерой и микрофоном позволяет разрабатывать интерактивные корпоративные и клиентские приложения, которые поддерживают голосовое взаимодействие и проведение видео-конференций.
  • Возможность для приложений Silverlight быть "доверенными" так же, как внебраузерные приложения открывает многие возможности, которые обеспечивают традиционные WPF-приложения, которые могут вызывать "родной" код за пределами "песочницы" на клиентской машине:

  • Поддержка позднего связывания с объектами, полученными от HTML DOM или от Automation API. Это обеспечивает возможность интеграции с COM-приложениями, такими как приложения Microsoft Office (например, Word, Excel, и Outlook) на Windows-клиентах и интеграцию других подключенных устройств.
  • Доступ к Папкам "Мои…" из приложения позволяет доступ ко всем папкам "Мои документы", "Мои видеозаписи", "Изображения", и "Музыка" для Windows и Mac и читать и записывать файлы из приложения, работающего в среде "песочницы".
  • Легкое развертывание и управление, избавляющее от необходимости использования междоменных файлов политик доступа (ClientAccess.xml или CrossDomainAcess.xml), а также возможность создания групповых политик для управления доверенными приложениями.
  • Silverlight 4 действительно включает несколько ключевых расширений, чтобы защитить, обработать и доставить более дружественные с медиа RIA:

  • Поддержка офлайнового управления цифровыми правами поможет доставить медиа в офлайновом режиме в более защищенной и управляемой среде.
  • Возможности интеграции с Web-камерой и микрофоном и возможность записи аудио и видео клиентской стороны, обеспечивают многочисленные возможности для разработки интерактивных аудио/видео RIA.
  • Следующие усовершенствования основной платформы и компонентов помогут улучшить интерфейс конечного пользователя и разрабатывать корпоративные приложения в режиме быстрой разработки.

  • Официальная поддержка web-браузера Google Chrome - это, вероятно, конечный шаг к провозглашению Silverlight кроссбраузерной платформой и, конечно, осчастливит фанатов Google.
  • Введение поддержки широковещательного сетевого взаимодействия по протоколу UDP поможет улучшить потребительские свойства и стабильность приложений, более эффективно используя сетевые ресурсы.
  • WCF-службы RIA помогают разрабатывать многозвенные приложения в режиме быстрой разработки.
  • Полная оптимизация производительности улучшает производительность запуска и выполнения приложений Silverlight 4 по сравнению с приложениями Silverlight 3.
  • Visual Studio 2010 позволяет разработку пользовательского интерфейса для приложений Silverlight 4 (и Silverlight 3) и вводит улучшенную привязку данных и интеграцию WCF-служб RIA, а также другие расширения, чтобы улучшить опыт разработки.
  • Silverlight 4 и инструментальные средства разработки Windows Phone допускают разработку интерактивных приложений Silverlight для мобильного телефонов серии Windows 7. Вы можете разрабатывать высококачественные медиа-приложения (включая интеграцию с видео камерой и микрофоном) для игровых приложений для мобильных телефонов Windows.
  • Обзор Silverlight 5

    Рассмотрим ожидаемые возможности релиза.

    Поддержка 64-битной платформы

    Даже Silverlight 4 не работает в 64-битных браузерах. Между тем, 32-бита уверенно уходят в прошлое. Именно поэтому, начиная с 5-й версии Silverlight, плагин будет доступен как в 32-битной, так и в 64-битной версиях. Предполагается, что пользователю не придется думать, какая из версий должна быть установлена.

    Улучшенное управление питанием

    Речь идет о том, что при просмотре видео с помощью Silverlight (а, следовательно, при отсутствии взаимодействия с мышью и клавиатурой), Вас не застанет врасплох установленный на машине Screensaver и Вам не придется бросаться к мыши, чтобы продолжить смотреть видео.

    Копирование изображений

    В Silverlight 4 появился класс Clipboard, который позволил копировать текст в буфер и обратно. Silverlight 5 расширяет возможности этого класса, позволяя работать с изображениями. Методы SetImage и GetImage будут работать с объектами типа BitmapSource. Также предусмотрено наличие метода ContainsImage, проверяющего наличие изображения в буфере.

    Поддержка 3D

    Речь идет не о технологии псевдо 3D, появившейся в Silverlight 4, а о полноценном 3D API с поддержкой аппаратного ускорения. Последнее уже хорошо зарекомендовало себя при работе с видео.

    Поддержка Behaviors и Triggers

    Поддержка Behaviors призвана перенести функциональность Поведений, реализованных в Blend, на уровень ядра Silverlight. Речь идет о создании комплексных объектов, объединяющих в себе ряд различных преобразований, создавая тем самым уникальное Поведение. И если ранее подобное можно было реализовать, только подключив специальную сборку из Blend, то теперь это все будет в ядре. Введение триггеров призвано еще больше сблизить WPF и Silverlight, хотя триггеры в Silverlight выглядят более универсальными.

    Layout transition

    В Silverlight 5 любому контейнеру будет можно задавать эффекты, связанные с заполнением контейнера и добавлением нового элемента. Благодаря Layout transition разработчику не придется работать с каждым элементом отдельно, а достаточно будет указать механизм заполнения для всего контейнера.

    Связывание с данными

    Отладка

    У разработчиков теперь будет меньше головной боли, так как появилась возможность ставить точки останова в коде, описывающем связывание данных. Достаточно поставить точку останова в XAML файле, на строке, описывающей Binding, и разработчик может получить всю возможную информацию о связывании и проблемах, возникающих с этим. Поэтому найти такие ошибки, как неправильное написание имени свойства или имени преобразователя типов, станет теперь проще.

    FindAncestor

    FindAncestor позволяет выполнять связку, выполняя поиск любого вышестоящего элемента, и выполнять с ним связывание.

    DataContextChanged

    Как видно, Silverlight 5 все ближе и ближе приближается к WPF. Новое событие DataContextChanged позволит определить изменение источника данных при связывании.

    Стили

    Связывание теперь можно будет использовать в Setter элементах стилей. Это позволит быстро менять внешний вид окна, задавая различные темы.

    Поддержка Full-Trust внутри браузера

    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>

    Поддержка выбора элементов в ItemsControl с клавиатуры

    Данный функционал достаточно простой, но приятный. Вспомните бесконечные элементы 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 появилась возможность создавать приложения с повышенными полномочиями, работающими в окне браузера. Рассмотрим процедуру создания таких приложений.

    Шаг 1.

    Приложение необходимо подписать сертификатом, что вполне можно сделать из оболочки Visual Studio в настройках проекта (рис. 7.1).

    (рис 7.1) Вкладка Signing

    Тут вы можете сгенерировать тестовый сертификат или выбрать его из хранилища (файла). Теоретически, если вы создаете приложение для работы внутри своей сети, сертификат можно и не покупать, а пользоваться тестовым.

    Шаг 2.

    Далее необходимо развернуть сертификат на машинах, где будет работать ваше Silverlight-приложение. Если вы хотите протестировать функциональность на рабочей машине, то это можно легко сделать, нажав кнопку More Details… в диалоге выше, перейдя к параметрам сертификата (рис. 7.2):

    (рис 7.2) Вкладка General

    Шаг 3

    На следующем этапе нужно у всех клиентов разрешить запуск приложений в браузере с повышенными полномочиями. Это можно сделать, установив значение AllowElevatedTrustAppsInBrowser (DWORD) в 0х00000000 (disabled) или 0?00000001 (enabled) в ключах HKEY_LOCAL_MACHINE\Software\Microsoft\Silverlight\ (для 32 бит) или HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Silverlight\ (для 64 бит).

    Шаг 4

    Необходимо внести изменения в конфигурационный файл таким образом, чтобы ваше приложение при работе с браузером запрашивало дополнительные полномочия. Это легко можно сделать в настройках проекта, выбрав соответствующую галочку (рис. 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

    Теперь при вызове этого диалогового окна, можно установить имя файла (как и список расширений), которое будет отображаться по умолчанию, как имя файла, предлагаемого для записи. Вот как это выглядит:

    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.

    P/Invoke

    В документации эта возможность пока не описана, но она уже реализована – возможность вызова методов 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, то механизма получить информацию о проблеме не было. В Silverlight 5 возможна отладка 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 четко позволяет выявить проблему и проверить правильность данных.

    Улучшенная поддержка шаблона MVVM

    Данная поддержка состоит в расширении перечислимого типа UpdateSourceTrigger значением PropertyChanged. Данное значение влияет на обновление источника данных, происходящее при обновлении цели (элемента, куда данные выгружаются). Ранее этот тип поддерживал лишь два значения, это LostFocus и Explicit. Иными словами, если Вы связываете данные с элементом управления 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 перешел в стадию Release Candidate. Выход финальной версии технологии по-прежнему намечен на конец 2011 года.

    Набор для практики

    Вопросы:

  • Назовите ключевые особенности Silverlight 4
  • Охарактеризуйте основные нововведения Silverlight 5, связанные с текстом
  • Повышение полномочий для приложений в браузере
  • Поддержка нескольких окон в Silverlight 5
  • Вернуться к учебному плану