Методика создания интерактивных приложений Silverlight

Практикум

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

Прежде, чем приступить к созданию приложений Silverlight 3, необходимо убедиться, что все необходимые системные компоненты установлены. Для создания приложений необходимы:

  • Microsoft Silverlight 3 windows runtime (Silverlight.exe)
  • Microsoft Visual Studio 2008 + SP1, язык C#
  • Microsoft Silverlight 3 Tools for Microsoft Visual Studio 2008 SP1 (Silverlight3_Tools.exe)
  • Microsoft Silverlight 3 SDK (silverlight_sdk.exe)
  • Microsoft Silverlight 3 Toolkit July 2009 (Silverlight 3 Toolkit July 2009.msi)
  • Microsoft .NET RIA Services (RiaServices.msi)
  • Microsoft Internet Explorer 8
  • Microsoft Expression Encoder 3.0
  • Microsoft Internet Information Server 7.0
  • Microsoft IIS Media Services 3.0 (IISMedia32.msi)
  • Microsoft SQL Server 2008 + Client
  • База данных - пример AdventureWorks
  • Microsoft Expression 3.0 (Deep Zoom Composer, Expression Encoder)
  • Для выполнения практических работ по данному курсу от студента необходимо начальное знание языка C# и способов работы с Visual Studio.

    Создание простого приложения Silverlight

    Целью данного занятия является первое знакомство с Silverlight и создание простого приложения Silverlight

    Задание

    Создать новый проект Silverlight, разместить (захостить) приложение Silverlight в веб-приложении. Разместить стандартные элементы управления на странице Button, TextBox, TextBlock. Добавить управляющий код C#, который текст, введенный в TextBox, по нажатию кнопки, отображает в элементе TextBlock.

    Создание приложения по шаблону

    В Visual Studio создадим новый проект

    (рис P.1) Создание нового проекта Silverlight

    Выберем шаблон Silverlight Application и зададим имя проекта SilverlightApplication

    (рис P.2) Выбор шаблона для проекта Silverlight

    Приложение Silverlight должно быть размещено на веб-странице сайта. Создадим такой сайт. Это будет веб-приложение ASP.NET с названием SilverlightApplication.Web

    (рис P.3) Создание веб-приложения для размещения приложения Silverlight

    После окончания работы мастера, должно получиться следующее решение, содержащее 2 проекта SilverlightApplication и SilverlightApplication.Web.

    (рис P.4) Получившееся решение Silverlight

    Добавление элементов управления

    На страницу MainPage.xaml добавим элементы управления StackPanel и внутрь ее элементы TextBlock, TextBox и Button. Откроем MainPage.xaml и с панели ToolBox перетащим эти элементы внутрь контейнера Grid.

    <Grid x:Name="LayoutRoot">
        <StackPanel Height="480" Width="257">
            <TextBlock x:Name="textBlock"/>
            <TextBox x:Name="textBox" Text="Введите текст"/>
            <Button Content="Кнопка" Click="Button_Click"/>
        </StackPanel>
    </Grid>

    Для TextBlock зададим имя textBlock, для того, чтобы к нему можно было обращаться из кода C#. Для TextBox зададим имя textBox. Кроме того, textBox содержит текст Введите текст. Кнопка Button содержит текст Кнопка и при нажатии на нее будет вызван метод Button_Click кода C#. Этот метод выглядит так:

    private void Button_Click
         (object sender, System.Windows.RoutedEventArgs e)
    {
        textBlock.Text = textBox.Text;
    }

    Из примера видно как код xaml вызывает метод C# void Button_Click. И как код C# управляет свойствами элементов, описанных в коде xaml.

    Заключение

    В данном практическом занятии был создан проект Silverlight, размещен на веб сайте. Добавлены стандартные элементы управления. Осуществлен доступ к свойствам элементов управления, описанных в xaml, из кода и, наоборот, из xaml к коду C#.

    Создание элементов управления

    Целью данного практического занятия является создание пользовательских "богатых" элементов управления на основе стандартных. Здесь мы воспользуемся возможностью Silverlight по созданю шаблонов и стилей для стандартных элементов управления. Для выполнения задания необходима Visual Studio.

    Задание

    Создать пользовательские элементы управления Button, ComboBox и ListBox. Разместить элементы каждый на отдельной странице. Создать меню для навигации по страницам с пользовательскими элементами управления. В проекте SilverlightControls добавим папку \Controls, куда поместим пользовательские элементы управления. В папке Views разместим страницы с этими элементами.

    Меню

    Создаем проект Silverlight, как в разделе "Создание простого приложения Silverlight", согласно рис. P.1, рис. P.2 и рис. P.3. Называем его SilverlightControls. Разница лишь в том, что используем шаблон Silverlight Navigation Application.

    (рис P.5) Создание проекта по шаблону Silverlight Navigation Application

    Шаблон создаст 2 пункта меню в MainPage.xaml, таких как About и Home, мы его расширяем пунктами Button, ComboBox, ListBox:

    <Border x:Name="LinksBorder" 
            Style="{StaticResource LinksBorderStyle}">
        <StackPanel 
            x:Name="LinksStackPanel" 
            Style="{StaticResource LinksStackPanelStyle}">
            <HyperlinkButton 
                x:Name="Link1" 
                Style="{StaticResource LinkStyle}" 
                NavigateUri="/Home" 
                TargetName="ContentFrame" 
                Content="home"/>
            <Rectangle Style="{StaticResource DividerStyle}"/>                    
            <HyperlinkButton 
                x:Name="Link2" Style="{StaticResource LinkStyle}" 
                NavigateUri="/About" 
                TargetName="ContentFrame" 
                Content="about"/>                    
            <Rectangle Style="{StaticResource DividerStyle}"/>                    
            <HyperlinkButton 
                x:Name="Link3" 
                Style="{StaticResource LinkStyle}"                                      
                NavigateUri="/ButtonPage" 
                TargetName="ContentFrame" 
                Content="Button"/>
            <Rectangle Style="{StaticResource DividerStyle}"/>                    
            <HyperlinkButton 
                x:Name="Link4" 
                Style="{StaticResource LinkStyle}" 
                NavigateUri="/ComboBoxPage" 
                TargetName="ContentFrame" 
                Content="ComboBox"/>
            <Rectangle Style="{StaticResource DividerStyle}"/>                    
            <HyperlinkButton 
                x:Name="Link5" 
                Style="{StaticResource LinkStyle}" 
                NavigateUri="/ListBoxPage" 
                TargetName="ContentFrame" 
                Content="ListBox"/>
        </StackPanel>
    </Border>

    Далее необходимо создать страницы и сами элементы управления.

    Элемент Button

    Добавляем новый пользовательский элемент управления ButtonControl.xaml (Add/New Item). Размещаем его в каталоге \Controls. Туда же добавим рисунки 4.jpg и SL.png.

    (рис P.6) Создание пользовательского элемента управления Button

    Добавим стандартный элемент Button

    <Button 
        x:Name="button1"             
        Content="Button1" 
        Click="Button_Click"
        Style="{StaticResource ImageButton}" 
        HorizontalAlignment="Left" Width="77"/>

    и улучшим его внешний вид с помощью стиля:

    <UserControl.Resources>
       <Style x:Key="TextBlockStyle" TargetType="TextBlock"> 
          <Setter Property="FontFamily" Value="Comic Sans Ms"/>
          <Setter Property="Text" Value="Click!"/>
          <Setter Property="Foreground" Value="MediumBlue"/>
          <Setter Property="FontSize" Value="15"/>
       </Style>
       <Style x:Key="ImageButton" TargetType="Button">
          <Setter Property="Template">
             <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Button>
                       <StackPanel Orientation="Vertical">
                          <Image 
                              Source="SL.png" 
                              Height="65" 
                              Width="65" 
                              Stretch="Fill"/>
                          <TextBlock 
                              Style="{StaticResource TextBlockStyle}" 
                              HorizontalAlignment="Center"/>
                       </StackPanel>
                    </Button>
                </ControlTemplate>
             </Setter.Value>
          </Setter>
       </Style>
    </UserControl.Resources>
  • Т.е. кнопка будет состоять из кнопки <Button/>. Эта кнопка является контейнером для <StackPanel/>, которая в свою очередь содержит <Image/> и <TextBlock/>. К текстовому блоку привязан стиль TextBlockStyle. К самой кнопке привязан стиль ImageButton.
  • Добавляем страницу ButtonPage.xaml для размещения этого элемента, страницу поместим в каталог \Views проекта.

    (рис P.7) Создание страницы для элемента управления Button

    На странице ButtonPage.xaml добавляем пространство имен класса SilverlightControls:

    xmlns:local="clr-namespace:SilverlightControls"

    и в сетку страницы сам элемент управления Button:

    <local:ButtonControl 
        VerticalAlignment="Top" 
        HorizontalAlignment="Center"/>

    После запуска мы получим:

    (рис P.8) Внешний вид пользовательского элемента управления Button

    Элемент ComboBox

    Добавляем новый пользовательский элемент управления ComboBoxControl.xaml (Add/New Item). Размещаем его в каталоге \Controls. Туда же добавим рисунки 1.jpg, 2.jpg и 3.jpg.

    (рис P.9) Создание пользовательского элемента управления ComboBox

    Добавим стандартный элемент ComboBox:

    <ComboBox 
       Margin="37,0,0,119" 
       Height="22" 
       VerticalAlignment="Bottom" 
       HorizontalAlignment="Left" 
       Width="65"/>

    Добавим три элемента, улучшим вид каждого элемента, с помощью шаблона:

    <ComboBox 
        Margin="37,0,0,119" 
        Height="22" 
        VerticalAlignment="Top" 
        HorizontalAlignment="Left" 
        Width="65">
        <ComboBoxItem>
            <StackPanel Orientation="Horizontal">
                <Image 
                    Height="100" 
                    Width="100" 
                    Source="1.jpg"/>
                <TextBlock 
                    Text="Ferrari F430" 
                    HorizontalAlignment="Right" 
                    VerticalAlignment="Center"/>
            </StackPanel>
        </ComboBoxItem>
        <ComboBoxItem>
            <StackPanel Orientation="Horizontal">
                <Image 
                    Height="100" 
                    Width="100" 
                    Source="2.jpg"/>
                <TextBlock 
                    Text="Fisker Karma" 
                    HorizontalAlignment="Right" 
                    VerticalAlignment="Center"/>
            </StackPanel>
        </ComboBoxItem>
        <ComboBoxItem>
            <StackPanel Orientation="Horizontal">
                <Image 
                    Height="100" 
                    Width="100" 
                    Source="3.jpg"/>
                <TextBlock 
                    Text="Lamborghini Murcielago LP 640" 
                    HorizontalAlignment="Right" 
                    VerticalAlignment="Center"/>
            </StackPanel>
        </ComboBoxItem>
    </ComboBox>

    Каждый пункт списка содержит вложенную панель <StackPanel/>, в которую вложены элементы <Image/> и <TextBlock/>.

    Добавляем страницу ComboBoxPage.xaml для размещения этого элемента, страницу поместим в каталог \Views проекта.

    (рис P.10) Создание страницы для элемента управления ComboBox

    На странице ComboBoxPage.xaml добавляем пространство имен класса SilverlightControls:

    xmlns:local="clr-namespace:SilverlightControls"

    и в сетку страницы сам элемент управления ComboBox:

    <local:ComboBoxControl 
        VerticalAlignment="Top" 
        HorizontalAlignment="Center"/>

    После компиляции проекта мы увидим ниспадающий список автомобилей с их изображениями:

    (рис P.11) Внешний вид пользовательского элемента управления ComboBox

    Элемент ListBox

    Добавляем новый пользовательский элемент управления ListBoxControl.xaml (Add/New Item). Размещаем его в каталоге \Controls.

    (рис P.12) Создание пользовательского элемента управления ListBox

    Добавим стандартный элемент ListBox:

    <ListBox 
        x:Name="_listbox"
        Margin="0,0,-2,0" 
        HorizontalAlignment="Center" 
        VerticalAlignment="Bottom">
        Width="229" 
        Height="230"
        <StackPanel Orientation="Horizontal">
            <Image Height="100" Width="100" Source="1.jpg"/>
            <TextBlock 
                Text="Ferrari F430" 
                HorizontalAlignment="Right" 
                VerticalAlignment="Center"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Image Height="100" Width="100" Source="2.jpg"/>
            <TextBlock 
                Text="Fisker Karma" 
                HorizontalAlignment="Right" 
                VerticalAlignment="Center"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Image Height="100" Width="100" Source="3.jpg"/>
            <TextBlock 
                Text="Lamborghini Murcielago LP 640" 
                HorizontalAlignment="Right" 
                VerticalAlignment="Center"/>
        </StackPanel>
    </ListBox>

    И добавим 3 пункта, с помощью шаблона. Шаблон содержит элемент <StackPanel/>, который содержит рисунок <Image/> и текст <TextBlock/>.

    Добавляем страницу ListBoxPage.xaml для размещения этого элемента, страницу поместим в каталог \Views проекта.

    (рис P.13) Создание страницы для элемента управления ListBox

    На странице ListBoxPage.xaml добавляем пространство имен класса SilverlightControls:

    xmlns:local="clr-namespace:SilverlightControls"

    и в сетку страницы сам элемент управления ListBox:

    <local:ListBoxControl 
        VerticalAlignment="Top" 
        HorizontalAlignment="Center"/>

    После компиляции проекта мы увидим список автомобилей с их изображениями:

    (рис P.14) Внешний вид пользовательского элемента управления ListBox

    Заключение

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

    Работа с базами данных

    На данном занятии должно быть разработано приложение Silverlight, которое соединяется с базой данных и работают с таблицами. Основные способы это:

  • Веб-сервисы: SOAP, ASP.NET web services (ASMX), WCF services, REST, .NET RIA Services.
  • Сокеты: network socket communication
  • Сокеты в данном практическом занятии рассматриваться не будут, т.к. это довольно сложный и устаревший способ доступа к данным. В данном примере рассмотрим RIA сервис, как наиболее изящный и простой способ подключения. Для работы с таблицами будем использовать элементы управления DataGrid и DataForm.

    Для выполнения задания необходимы Visual Studio, SQL Server+Client.

    Задание

    Разработать приложение Silverlight соединяющееся с базой данных AdventureWorks (база данных - пример) и извлекающее данные из таблицы Product. Данная база работает под управлением СУБД MS SQL Server 2008. Задача состоит из этапов:

  • Создание нового проекта Silverlight
  • Создание нового проекта ASP.NET
  • Создание модели данных в проекте ASP.NET
  • Создание сервиса для отображения модели данных ASP.NET
  • Создание элементов управления в проекте Silverlight
  • DataGrid - табличный элемент управления для отображения содержимого таблицы Product
  • DataForm - элемент управления для отображения и редактирования содержимого одной строки таблицы Product для выбранного в DataGrid продукта
  • TextBlock - для подписей
  • Button - элемент управления для сохранения и удаления строк.
  • Асинхронный запрос к веб-сервису для получения содержимого Product
  • Отображение данных списков в соответствующих элементах управления
  • Сортировка, группировка, постраничный показ, фильтрация строк в DataGrid.
  • Редактирование данных в DataForm
  • Для выполнения данного задания необходимо установленное программное обеспечение (см. раздел 1 "Введение"), а также, работающая СУБД SQL Server 2008 с базой данных AdventureWorks (прилагается файл с базой) и клиентская часть данной СУБД. Необходимо отметить значение .NET RIA Services для выполнения этого задания. Данная служба является опцией Internet Information Server и устанавливается на веб-сервер.

    Описание таблиц Product

    Ниже приведена структура таблицы Product.

    (рис P.15) Описание таблицы Product

    Создание приложения

    В Visual Studio 2008 создаем новый проект Silverlight под названием DatabaseSilverlightApplication, по шаблону Silverlight Application.

    (рис P.16) Создание проекта DatabaseSilverlightApplication

    Во время создания укажите привязку к .NET RIA Services, которые будут использованы для получения более высокого функционала приложения легким способом.

    (рис 4.3) Добавление расширений .NET RIA Services

    После окончания работы мастера будет создано решение, состоящее из двух проектов:

    (рис P.17) Проекты DatabaseSilverlightApplication и DatabaseSilverlightApplication.Web

    Далее открываем MainPage.xaml и MainPage.xaml.cs и работаем с ними.

    Создание источника данных

    Для того чтобы отображать данные на клиенте, необходимо создать источник данных DataContext в веб-приложении DatabaseSilverlightApplication.Web. Это делается в два этапа. Сначала создается модель данных, затем веб-сервис.

    Чтобы создать модель, добавляем новый пункт new item и выбираем ADO.NET Entity Data Model.

    (рис P.18) Добавление ADO.NET Entity Data Model

    Выбираем автоматическую генерацию модели из базы данных

    (рис P.19) Генерация модели из базы данных

    Создаем подключение веб-приложения к базе данных. Генерируем новое соединение, выбираем имя сервера и имя базы данных, тестируем соединение.

    (рис P.20) Создание подключения к базе данных

    После того, как мастер подключится к базе данных и прочитает там список доступных объектов, выбираем нужная таблица Product.

    (рис P.21) Выбор объектов базы данных для создания сущностей

    Теперь необходимо создать веб-сервис. Для начал нужно построить (build) веб-приложение. Для того чтобы, модель отразилась в dll и была видна для мастера создания сервиса. Добавляем пункт new item и выбираем Domain Service Class

    (рис P.22) Добавление веб-сервиса Domain Service Class

    Затем мастер предложит выбрать таблицы для отражения их в веб-сервисе.

    (рис 4.10) Добавление сущностей в веб-сервис

    Выбираем все и указываем возможность редактирования. Мастер сгенерирует все необходимые для этого методы. GetProduct() - для выборки данных, InsertProduct(Product product) - для добавления строки, UpdateProduct(Product currentProduct) - для модификации и DeleteProduct(Product product) - для удаления.

    (рис P.23) Методы для работы с сущностями

    Теперь переходим непосредственно к проекту DatabaseSilverlightApplication.

    Вывод данных таблицы

    Добавляем на страницу MainPage.xaml элемент управления DataGrid. Он будет служить для отображения данных таблицы Product. Его название productGrid, он будет получать данные из источника данных ProductsData. Выводить мы будем только выбранные поля Color, Name, ModifiedDate, ProductNumber, ListPrice, Weight, WeightUnitMeasureCode, MakeFlag, FinishedGoodsFlag, ProductLine, Size, SizeUnitMeasureCode и StandardCost. Значение свойства AutoGenerateColumns надо задать False. Если этого не сделать, тогда будут выведены все поля плюс эти поля таблицы Product.

    <data:DataGrid 
        x:Name="productGrid" 
        Margin="0,22,318,0"
        ItemsSource="{Binding Data, ElementName=ProductsData}" 
        AutoGenerateColumns="False" >
        <data:DataGrid.Columns>
            <data:DataGridTextColumn
            Header="Color"
            Binding="{Binding Color}"/>
            <data:DataGridTextColumn
            Header="Name"
            Binding="{Binding Name}"/>
            <data:DataGridTextColumn
            Header="Modified"
            Binding="{Binding ModifiedDate}"/>
            <data:DataGridTextColumn
            Header="ProductNumber"
            Binding="{Binding ProductNumber}"/>
            <data:DataGridTextColumn
            Header="Price"
            Binding="{Binding ListPrice}"/>
            <data:DataGridTextColumn
            Header="Weight"
            Binding="{Binding Weight}"/>
            <data:DataGridTextColumn
            Header="Unit"
            Binding="{Binding WeightUnitMeasureCode}"/>
            <data:DataGridCheckBoxColumn
            Header="Make"
            Binding="{Binding MakeFlag}"/>
            <data:DataGridCheckBoxColumn
            Header="Finished"
            Binding="{Binding FinishedGoodsFlag}"/>
            <data:DataGridTextColumn
            Header="ProductLine"
            Binding="{Binding ProductLine}"/>
            <data:DataGridTextColumn
            Header="Size"
            Binding="{Binding Size}"/>
            <data:DataGridTextColumn
            Header="Unit"
            Binding="{Binding SizeUnitMeasureCode}"/>
            <data:DataGridTextColumn
            Header="StandardCost"
            Binding="{Binding StandardCost}"/>
        </data:DataGrid.Columns>
    </data:DataGrid>

    Чтобы создать источник данных ProductsData, добавляем ссылку reference на библиотеку System.Windows.Ria.Controls:

    (рис P.24) Создание ссылки для элементов управления RIA

    На страницу MainPage.xaml добавляем:

    xmlns:ria="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls"
    xmlns:riaData="clr-namespace:System.Windows.Data;assembly=System.Windows.Ria.Controls"

    Добавляем источник данных ProductsData на страницу:

    <UserControl.Resources> 
        <ria:DomainDataSource 
            x:Name="ProductsData" 
            AutoLoad="True"
            QueryName="GetProductQuery">
            <ria:DomainDataSource.DomainContext>
                <DatabaseSilverlightApplication_Web:ProductContext/>
            </ria:DomainDataSource.DomainContext>            
        </ria:DomainDataSource> 
    </UserControl.Resources>

    Здесь указан метод GetProductQuery, возвращающий данные из базы и контекст, в который эти данные загружаются ProductContext. В атрибуты элемента DataGrid вставляем привязку к контексту ProductsData:

    <data:DataGrid 
        ItemsSource="{Binding Data, ElementName=ProductsData}"

    Теперь можно запустить приложение:

    (рис P.25) Отображение данных таблицы

    Теперь добавим интересный элемент управления "бегунок" ActivityControl.dll add reference. Данный элемент не является продуктом Microsoft и скачивается отдельно http://www.davidpoll.com/Download/ActivityControl9-14.zip

    (рис P.26) Создание ссылки для элемента управления ActivityControl

    Обновим пространство имен страницы MainPage.xaml

    xmlns:activity="clr-namespace:System.Windows.Controls;assembly=ActivityControl"

    И добавим этот элемент на страницу, поместив описание DataGrid внутрь этого элемента:

    <activity:Activity 
    	IsActive="{Binding IsBusy, ElementName=ProductsData}">
        <data:DataGrid

    Видим, что во время загрузки данных индикатор загрузки работает, а после исчезает:

    (рис P.27) Элемент управления ActivityControl

    Сортировка

    Сортировка строк осуществляется методами самого элемента DataGrid. Свойство задается в описании DataGrid.

    CanUserSortColumns="True"

    По умолчанию значение свойства - True. По нажатию на поле осуществляется сортировка по возрастанию, при повторном нажатии - по убыванию.

    Постраничный вывод

    Теперь добавим элемент, который будет осуществлять Paging, т.е. постраничный вывод данных, разбитие их на страницы. Для этого служит элемент DataPager. Добавляем его на страницу:

    <data:DataPager
        Source="{Binding Data, ElementName=ProductsData}"                        
        PageSize="10"

    Привязываем этот элемент к данным ProductsData, так же как привязывали данные к DataGrid.

    Группировка

    Теперь добавим возможность группировки данных. Это можно сделать в коде:

    public MainPage()
    {
        InitializeComponent();
        ProductsData.GroupDescriptors.Add(new GroupDescriptor("Color"));
    }

    Можно в описании xaml, добавив как свойство GroupDescriptor из набора GroupDescriptors источника данных:

    <ria:DomainDataSource 
     …
        <ria:DomainDataSource.GroupDescriptors>
            < riaData:GroupDescriptor PropertyPath="Color"/>            
        </ria:DomainDataSource.GroupDescriptors>
    </ria:DomainDataSource>

    Полей для группировки может быть несколько:

    <riaData:GroupDescriptor PropertyPath="ProductLine"/>
    <riaData:GroupDescriptor PropertyPath="Color"/>
    
    ProductsData.GroupDescriptors.Add(new GroupDescriptor("ProductLine"));
    ProductsData.GroupDescriptors.Add(new GroupDescriptor("Color"));

    Это будет выглядеть так:

    (рис P.28) Группировка строк в DataGrid

    Фильтрация

    Добавим на страницу xaml поле для ввода фильтра FilterText:

    <TextBlock Text="Filter Name:"/>
    <TextBox x:Name="FilterText" TextChanged="FilterText_TextChanged"/>

    В описание источника данных добавляем описание фильтра:

    <ria:DomainDataSource 
        <ria:DomainDataSource.FilterDescriptors>
            <riaData:FilterDescriptorCollection>
                <riaData:FilterDescriptor 
                    PropertyPath="Name" 
                    Operator="Contains">
                    <riaData:ControlParameter 
                        ControlName="Filter" 
                        PropertyName="Text" 
                        RefreshEventName="TextChanged" />
                </riaData:FilterDescriptor>
            </riaData:FilterDescriptorCollection>
        </ria:DomainDataSource.FilterDescriptors>
    </ria:DomainDataSource>

    Обратите внимание на атрибут Operator. RIA сервисы предлагают дополнительные условия фильтрации:

    (рис P.29) Условия фильтрации

    Либо в коде добавляем обработчик событий:

    private void FilterText_TextChanged
        (object sender, System.Windows.Controls.TextChangedEventArgs e)
    {
        FilterDescriptorCollection fcollection = 
            new FilterDescriptorCollection();
        FilterDescriptor fdescr = 
            new FilterDescriptor
                ("Name", FilterOperator.Contains, FilterText.Text);
        fcollection.Add(fdescr);
        ProductsData.FilterDescriptors = fcollection;
    }

    Получаем работающий фильтр:

    (рис P.30) Фильтрация строк в DataGrid

    Теперь перейдем к изменению данных в таблице. Добавим в MainPage.xaml элемент управления DataForm:

    <dataFormToolkit:DataForm 
        x:Name="productEditForm"             
        CurrentItem="{Binding 
                      ElementName=productGrid, Path=SelectedItem}"
        AutoCommit="False"
        AutoEdit="True"
        Header="Details"/>

    Как видно из описания, он привязан к другому элементу productGrid, и при выборе строки SelectedItem отображает содержимое всей строки таблицы базы данных.

    Получается приложение такого вида:

    (рис P.31) Детализация с помощью элемента управления DataForm

    Изменения данных (было Blue, стало Green ) отслеживаются этим элементом. Видно появление звездочки вверху элемента, кнопки OK и отмена активизировались и появились изменения в DataGrid. После нажатия кнопки OK изменения появятся и в источнике данных и. Можно тоже самое сделать с помощью кода. Для манипуляции с данными к этому добавим панель с кнопками, код C# и изменим описание DataForm. Добавим в DataForm:

    <dataFormToolkit:DataForm 
        CommandButtonsVisibility="None"

    Добавим панель с кнопкой сохранения изменений:

    <StackPanel Orientation="Horizontal" 
                Height="23" 
                VerticalAlignment="Bottom">
        <Button Content="Save changes" 
                Click="Button_Click"/>
    </StackPanel>

    И метод в код страницы:

    private void Button_Click
        (object sender, RoutedEventArgs e)
    {
        productEditForm.CommitEdit();
        ProductsData.SubmitChanges();
    }

    Для удаления строки добавим кнопку удалить со следующим описанием:

    <Button Content="Delete" 
            Click="ButtonDelete_Click"/>

    И код C#:

    private void ButtonDelete_Click(object sender, RoutedEventArgs e)
    {
        productEditForm.CommitEdit();
        productEditForm.DeleteItem();
        ProductsData.SubmitChanges();
    }

    Заключение

    На данном практическом занятии мы рассмотрели пример работы с базой данных MS SQL 2008, с таблицами, научились делать выборку, сортировать, группировать и фильтровать строки, удалять, изменять данные таблиц, а также, оценили роль .NET RIA Services, значительно упрощающих разработку приложения Silverlight. Исходный код данного примера приведен в файле DataBase.zip.

    Работа с веб сервисами

    Задание

    Задачей данного занятия является использование веб-сервиса Аэрофлота для создания приложения Silverlight, дающего возможность просматривать авиа рейсы прибывающие и вылетающие для заданного аэропорта мира и на заданную дату. Задача состоит из этапов:

  • Создание нового проекта Silverlight
  • Подключение к веб-сервису из приложения Silverlight по адресу в Интернете http://webservices.aeroflot.ru/flightstatus.asmx?WSDL
  • Создание элементов управления
  • ComboBox - для отображения списка аэропортов
  • ComboBox - для отображения списка дат, на которые доступна информация о рейсах
  • Button - кнопка начала поиска
  • DataGrid - табличный элемент управления для отображения вылетающих рейсов
  • DataGrid - табличный элемент управления для отображения прибывающих рейсов
  • TextBlock - для подписей к DataGrid
  • Асинхронный запрос к веб-сервису для получения списка аэропортов
  • Асинхронный запрос к веб-сервису для получения списка дат
  • Асинхронный запрос к веб-сервису для получения списка вылетающих рейсов
  • Асинхронный запрос к веб-сервису для получения списка прибывающих рейсов
  • Отображение данных списков в соответствующих элементах управления
  • Для выполнения данной работы необходимо установленное программное обеспечение (см. раздел 1 "Введение"), а также, доступ в Интернет.

    Описание веб-сервиса "Справка о рейсе/Табло аэропортов"

    Данный сервис позволяет получать информацию о текущем состоянии рейсов, просматривать табло аэропортов. Сервис предоставляет следующий набор функций:

  • AirportList - список аэропортов
  • AirportInfo - информация об аэропорте по его коду
  • DateList - список дат, за которые есть информация
  • Arrival/Departure - информация о прибытии/отправлении рейсов
  • FlightSearch - поиск рейса по номеру
  • FlightInfo - подробная информация о текущем состоянии рейса (по ключу, полученному в результате вызова Arrival/Departure/FlightSearch ).
  • AirportList - Список аэропортов. Возвращается список структур, состоящих из следующих полей:

  • city - город
  • name - название аэропорта
  • code - код аэропорта
  • AirportInfo - Информация об аэропорте. Входные параметры:

  • code - код аэропорта
  • Возвращается структура, состоящая из следующих полей:

  • city - город
  • name - название аэропорта
  • code - код аэропорта
  • Arrival - Табло прилета. Входные параметры:

  • code - код аэропорта
  • date - дата
  • order_field - поле (' airport ', ' sched ', ' plan ', ' company ', ' flight_no '), по которому идет сортировка
  • order - направление сортировки (' desc ', ' asc ')
  • Возвращается список структур, состоящих из следующих полей:

  • flt_pk - код рейса
  • company - код авиакомпании
  • flight_no - номер рейса
  • airport_inter - название промежуточного аэропорта
  • airport - название аэропорта отправления
  • sched - время прибытия по расписанию
  • plan - планируемое время прибытия
  • fact - фактическое время прибытия
  • calc - расчетное время прибытия
  • estimated arrival time
  • real - время посадки
  • union_flight_no - номер, объединенного рейса
  • status - статус рейса
  • DateList - Список дат, за которые есть данные в системе

    Departure - Табло вылета. Входные параметры:

  • code - код аэропорта
  • date - дата
  • order_field - поле (' airport ', ' sched ', ' plan ', ' company ', ' flight_no '), по которому идет сортировка
  • order - направление сортировки (' desc ', ' asc ')
  • Возвращается список структур, состоящих из следующих полей:

  • flt_pk - код рейса
  • company - код авиакомпании
  • flight_no - номер рейса
  • airport_inter - название промежуточного аэропорта
  • airport - название аеропорта назначения
  • sched - время вылета по расписанию
  • plan - планируемое время вылета
  • fact - фактическое время вылета
  • real - время взлета
  • union_flight_no - номер, объединенного рейса
  • status - статус рейса
  • is_check - признак регистрации ( 1 - идет, 0 - нет)
  • is_board - признак посадки в самолет ( 1 - идет, 0 - нет)
  • FlightInfo - Подробная информация о рейсе. Входные параметры:

  • flt_pk - код рейса
  • Возвращается список структур, состоящих из следующих полей:

  • company - код авиакомпании
  • flight_no - номер рейса
  • flight_type - тип рейса
  • aircraft_type - тип самолета
  • bort - номер самолета (борта)
  • seats_f - количество мест первого класса
  • seats_c - количество мест бизнес-класса
  • seats_y - количество мест эконом-класса
  • sched_dep - время вылета по расписанию
  • sched_arr - время прибытия по расписанию
  • plan_dep - планируемое время вылета
  • plan_arr - планируемое время прибытия
  • fact_dep - фактическое время вылета
  • fact_arr - фактическое время прибытия
  • real_dep - время взлета
  • real_arr - время посадки
  • calc - расчетное время прибытия
  • status - статус рейса
  • city_dep - город отправления
  • airport_dep - название аеропорта отправления
  • code_dep - код аэропорта отправления
  • terminal_dep - номер терминала аэропорта отправления
  • city_arr - город назначения
  • airport_arr - название аеропорта назначения
  • code_arr - код аэропорта назначения
  • terminal_arr - номер терминала аэропорта назначения
  • FlightSearch - Поиск рейсов. Входные параметры:

  • flight_no - номер рейса
  • flight number
  • Возвращается список структур, состоящих из следующих полей:

  • flt_pk - код рейса
  • company - код авиакомпании
  • flight_no - номер рейса
  • airport_dep - название аэропорта отправления
  • airport_inter - название промежуточного аэропорта
  • airport_arr - название аеропорта назначения
  • sched_dep - время вылета по расписанию
  • Адрес данного веб-сервиса:

    http://webservices.aeroflot.ru/flightstatus.asmx?WSDL

    Создание приложения Silverlight и подключение к веб-сервису

    Теперь создадим приложение Silverlight, а также веб-приложение для отображения приложения Silverlight. Для этого последовательно выполняем шаги, изображенные на рис.5.1 - рис. 5.4. В Visual Studio 2008 создаем новый проект, указываем шаблон "Silverlight Application", вводим название и каталог будущего проекта.

    (рис P.32) Создание проекта Silverlight

    Во время работы мастера отвечаем на вопрос, где будет "хоститься" новое приложение. Указываем, что на новом веб-сервере. Visual Studio создаст по шаблону простейшее веб-приложение ASP.NET и разместит на его странице необходимые ссылки на приложение Silverlight.

    (рис P.33) Создание веб проекта

    В результате работы мастера Visual Studio будет создано решение (см. рис.5.3)

    (рис P.34) Внешний вид нового проекта

    Далее кликаем на проекте Silverlight правой клавишей мыши и выбираем "Add Service Reference". В поле "Address" вводим адрес веб-сервиса в интернете: http://webservices.aeroflot.ru/flightstatus.asmx?WSDL. Сразу увидим контракт, предлагаемый веб-сервисом. Вводим пространство имен для данной ссылки.

    (рис P.35) Подключение к веб-сервису Аэрофлота

    Работа с веб-сервисом

    После подключения к веб-сервису Аэрофлота создаем интерфейс для посылки запросов к нему и отображения результата. Теперь необходимо изменить содержимое файла MainPage.xaml, как показано ниже:

    <UserControl
        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" 
        mc:Ignorable="d" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" 
        xmlns:dataFormToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit" 
        xmlns:AEROSilverlightApplication_FlightStatusReference="clr-namespace:AEROSilverlightApplication.FlightStatusReference" 
        xmlns:local="clr-namespace:AEROSilverlightApplication" 
        x:Class="AEROSilverlightApplication.MainPage"
        d:DesignWidth="640" d:DesignHeight="480">
        <StackPanel x:Name="LayoutRoot" >
            	<ComboBox
            		x:Name="airoportListBox"
    			Width="200" 
                    	HorizontalAlignment="Left" 
                    	SelectedIndex="0">
            		<ComboBoxItem Content="Список аэропортов"/>
            	</ComboBox>
            	<ComboBox                                    
            		x:Name="dateListBox" 
    			Width="200" 
               	HorizontalAlignment="Left" 
                    	SelectedIndex="0">
            		<ComboBoxItem Content="Доступные даты"/>
            	</ComboBox>
            	<Button 
            		Click="Button_Click" 
            		Content="Искать рейсы"
    			Width="200" 
                    	HorizontalAlignment="Left"/>
            	<TextBlock Text="Отправление"/>
            	<data:DataGrid x:Name="departureListGrid" 
                               HorizontalAlignment="Left"/>
            	<TextBlock Text="Прибытие"/>
            	<data:DataGrid x:Name="arrivalListGrid" 
                               HorizontalAlignment="Left"/>
        </StackPanel>
    </UserControl>

    В данном файле описаны 2 элемента управления ComboBox. airoportListBox - содержит список аэропортов всего мира, dateListBox - список дат, на которые имеются данные о рейсах. Элементы управления TextBlock - соответствующие надписи для элементов DataGrid. Эти элементы отображают список рейсов прибывающих ( arrivalListGrid ) и вылетающих ( departureListGrid ) в заданный день с выбранного аэропорта. Имеется кнопка Button, при нажатия которой (событие Button_Click ) выполнится обращение к веб-сервису, а результат будет занесен в элементы DataGrid.

    После этого переходим к редактированию кода страница code-behind. Содержимое файла MainPage.xaml.cs приведено ниже:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using AEROSilverlightApplication.FlightStatusReference;
    using System.Collections.ObjectModel;
    using System.Collections;
    
    namespace AEROSilverlightApplication
    {
        public partial class MainPage : UserControl
        {
            public FlightStatusSoapClient flightStatusClient;
            public MainPage()
            {
                InitializeComponent();            
                flightStatusClient = 
                    new FlightStatusSoapClient();
                flightStatusClient.AirportListCompleted += 
                    new EventHandler<AirportListCompletedEventArgs>
                        (flightStatusClient_AirportListCompleted);
                flightStatusClient.DateListCompleted += 
                    new EventHandler<DateListCompletedEventArgs>
                        (flightStatusClient_DateListCompleted);
                flightStatusClient.AirportListAsync();
                flightStatusClient.DateListAsync();
            }
            private void Button_Click
                (object sender, RoutedEventArgs e)
            {
                string code = 
                    airoportListBox.SelectedItem.ToString().Substring(0, 3);
                string date = 
                    dateListBox.SelectedItem.ToString();
                flightStatusClient.DepartureCompleted += 
                    new EventHandler<DepartureCompletedEventArgs>
                        (flightStatusClient_DepartureCompleted);
                flightStatusClient.ArrivalCompleted += 
                    new EventHandler<ArrivalCompletedEventArgs>
                        (flightStatusClient_ArrivalCompleted);
                flightStatusClient.DepartureAsync(code, date, "sched", "asc");
                flightStatusClient.ArrivalAsync(code, date, "sched", "asc");
            }
            void flightStatusClient_ArrivalCompleted
                (object sender, ArrivalCompletedEventArgs e)
            {
                arrivalListGrid.ItemsSource = e.Result;
            }
            void flightStatusClient_DepartureCompleted
                (object sender, DepartureCompletedEventArgs e)
            {
                departureListGrid.ItemsSource = e.Result;
            }
            void flightStatusClient_DateListCompleted
                (object sender, DateListCompletedEventArgs e)
            {
                IEnumerable<DateTime> query = 
                    e.Result.OrderBy(date => date);
                IEnumerable<string> query1 = 
                    query.Select<DateTime, string>
                    (date => date.ToShortDateString());
                dateListBox.Items.Clear();
                dateListBox.ItemsSource = query1;
            }
            void flightStatusClient_AirportListCompleted
                (object sender, AirportListCompletedEventArgs e)
            {
                IEnumerable<Airport> query = 
                    e.Result.OrderBy(Airport => Airport.city);
                IEnumerable<string> query1 = 
                    query.Select<Airport, string>
                    (Airport => Airport.code + ' ' + Airport.city);
                airoportListBox.Items.Clear();
                airoportListBox.ItemsSource = query1;
            }
        }
    }

    Рассмотрим код. Конструктор класса MainPage(). Вначале при загрузке страницы создается экземпляр класса FlightStatusSoapClient. Он необходим для асинхронного вызова данных. Затем асинхронно вызываем методы этого класса AirportListAsync() и DateListAsync(), для того, чтобы получить список аэропортов и дат. Добавляем обработчики событий AirportListCompleted и DateListCompleted, для того чтобы принять и обработать полученные данные.

    После того, как пользователь выбрал дату и аэропорт из списка, например, аэропорт Вены и 8 октября 2009 г, и нажал кнопку поиска, при срабатывают события Button_Click, заданное в xaml файле Click="Button_Click".

    После этого будут вызваны асинхронные методы, получающие от веб-сервиса списки рейсов прибывающих и вылетающих.

    После завершения отладки приложения можно увидеть результат (см. рис.P.36)

    (рис P.36) Работа приложения с веб-сервисом

    Выбран аэропорт Вены, дата 8 октября 2009 г. Мы видим 2 рейса отправляющихся в Москву и два рейса прибывающих из Москвы в этот день.

    Заключение

    В данном разделе рассмотрен пример создания приложения для работы с веб-сервисом Аэрофлота. Исходный код рассмотренного решения расположен в каталоге AERO.

    Smooth Streaming и Expression Encoder

    Целью данного практического занятия является изучение средства Expression Encoder из состава Microsoft Expression 3.0.

    Задание

    Разработать приложение Silverlight, приложение должно содержать медиаплеер, медиаплеер должен воспроизводить фильм, используя технологию Smooth Streaming. Одним из козырей этой технологии является поддержка различных битрейтов для видео. На данном занятии необходимо создать видеофайлы со следующими битрейтами: 2500, 1000 и 200 кбит/с. Для выполнения задания необходимы Microsoft Expression Encoder и Visual Studio. Кроме того, необходим сервер Internet Information Server и установлена служба IIS Media Services, которая является дополнением к IIS.

    Создание медиафайлов

    В среде Expression Encoder импортировать медифайл "Asteroid Impact_mpeg4.avi" для обработки. Характеристики данного файла: разрешение - HD 1280x720, соотношение сторон - 16:9, частота кадров - 29,97, видео кодек - mpeg4, битрейт видео - 2500, аудио кодек - mp3, битрейт аудио - 192, формат файла (контейнер) - AVI. Во время импорт Expression Encoder анализирует все свойства видео.

    (рис P.37) Импорт видеофайла в Expression Encoder

    После завершения анализа будут показаны характеристики файла и потока внизу на панели управления "Media content".

    (рис P.38) Параметры видеофайла в Expression Encoder

    Теперь необходимо создать набор выходных файлов с заданным битрейтом. Значение свойства "Output Format" задаем "IIS Smooth Streaming".

    (рис P.39) Выбор выходного формата видео

    Заключение

    Исходный код находится в файле SmoothStreaming.zip.

    Deep Zoom и Deep Zoom Composer

    На данном занятии должно быть разработано приложение Silverlight, которое предоставляет доступ к графической информации с помощью технологии Deep Zoom. Для выполнения задания необходимы средства разработки Microsoft Visual Studio 2008 и Deep Zoom Composer 3.0.

    Задание

    Создать проект в Deep Zoom Composer "автопортреты", экспортировать проект Deep Zoom в проект Silverlight и ASP.NET.

    Создание проекта Deep Zoom

    Откроем Deep Zoom Composer и создаем новый проект "автопортреты".

    (рис P.40) Создание проекта Deep Zoom

    Добавим автопортреты художников прошлого. Это картинки Леонардо да Винчи.jpg (464x650 пикселов), Лоренцо Джованни.jpg (650x831), Никола Пуссен.jpg (500x594), Рафаэль Санти.jpg (500x696) и Филиппино Липпи.jpg (460x661).

    (рис P.41) Добавление изображений в проект Deep Zoom

    После добавления увидим добавленные изображения справа. Переходим к составлению композиции по вкладке " Compose ".

    (рис P.42) Добавленные изображения в проект Deep Zoom

    На панели размещаем импортированные изображения, как позволяет фантазия дизайнера. Deep Zoom Composer позволяет масштабировать изображения как угодно. Например:

    (рис P.43) Составление композиции Deep Zoom

    Помимо простого размещения изображений на полотен, Deep Zoom Composer позволяет управлять переходами между картинками с помощью специальных элементов управления. Deep Zoom Composer позволяет делать слайдшоу, переход при нажатии на изображение как внутри композиции, так и по внешней интернет ссылке URL.

    Чтобы создать слайдшоу, необходимо открыть панель "Slideshow" и методом dragdrop перетащить изображения на панель. Создаем нужный порядок. Кнопкамиэтот порядок можно изменить.

    (рис P.44) Изготовление слайдшоу Deep Zoom

    Чтобы создать меню, необходимо открыть панель "Menu" и методом dragdrop перетащить изображение на панель меню. Название дается автоматически по имени файла, но мы можем его переименовать. Кнопкойможно автоматически создать дерево меню (default menu), согласно вложенности изображений друг в друга. Меню Deep Zoom Composerпозволяет (слева направо):

  • автоматическое создание меню по-умолчанию
  • удаление пункта меню
  • создание нового пункта меню
  • повышение уровня вложенности пункта меню
  • понижение уровня вложенности пункта меню
  • изменение порядка пункта меню вверх
  • изменение порядка пункта меню вниз
  • (рис P.45) Создание меню Deep Zoom

    Чтобы создать систему внутренних переходов, необходимо открыть панель "Internal Links", щелкнуть правой клавишей мыши по изображению, нажатие на которое приведет к переходу, "Add Internal Links".

    (рис P.46) Добавление внутренней ссылки

    И затем выбрать изображение, на которое произойдет переход.

    (рис P.47) Добавление внутренней ссылки. Выбор ссылки

    Чтобы создать систему внешних ссылок, необходимо выбрать в главном меню Deep Zoom Composer выбрать пункт "Tools/Manage External Links". И задать URL ссылки, отображаемое название и описание ссылки. Имя ссылки "Энциклопедия замечательных людей" адрес http://www.abc-people.com/data/bernini/work-1.htm.

    (рис P.48) Добавление внешней ссылки

    Затем методом dragdrop перетащить изображение "Бернини" на панель внешних ссылок. Откроется окно выбора внешних ссылок. Выбираем нужную ссылку. При нажатии на "Бернини" произойдет переход на сайт с его жизнеописанием.

    (рис P.49) Привязка внешней ссылки к изображению

    К одной ссылке можно привязать несколько изображений.

    Создание проекта Silverlight

    Для создания проекта Silverlight, который будет отображать проект Deep Zoom, необходимо экспортировать проект Deep Zoom в Visual Studio. Переходим по вкладке "Export".

    (рис P.50) Экспорт проекта Deep Zoom в проект Silverlight

    Перед экспортом можно сделать preview. Выбираем параметры экспорта тип: Silverlight Deep Zoom, экспортировать как коллекцию рисунков. Можно экспортировать в один большой рисунок. Шаблон выбираем "Blend 3 Behaviors + Source". Затем откроем папку нового проекта и откроем файл решения DeepZoomProject.sln из каталога silverlightdeepzoom. Мастер создаст следующее решение:

    (рис P.51) Экспорт Deep Zoom в проект Silverlight по шаблону "Blend 3 Behaviors + Source"

    Если запустить отладку debug, то получим следующее приложение Silverlight.

    (рис P.52) Пример работающего приложения Silverlight Deep Zoom

    Заключение

    В данной практической работе был рассмотрен пример создание приложения Silverlight Deep Zoom с помощью инструментов дизайнера Deep Zoom Composer 3.0 и программиста Visual Studio 2008. Исходный код находится в файле DeepZoom.zip.

    Создание внебраузерного приложения Silverlight

    Для выполнения данного практического задания необходимо средство разработки Visual Studio.

    Задание

    Разработать простейшее приложение Silverlight. Модифицировать его для установки на клиентском компьютере, инсталлировать и деинсталлировать приложение. Модифицировать приложение, чтобы оно могло быть обновлено, обновить приложение. Модифицировать приложение, чтобы оно могло определять наличие подключения к Интернет, проверить работу отключив сетевой интерфейс.

    Установка на клиентском компьютере

    Создаем проект Silverlight, как описано в разделе " Создание простого приложения Silverlight", согласно рис. P1, рис. P.2 и рис. P.3. Добавляем в проект файл (Add existing Item) - иконку . Открываем свойства проекта Silverlight. И включаем свойство "Enable running application out of the browser". Кроме этого задаем свойства "Out-Of-Browser Settings". Используем в качестве иконки добавленный рисунок.

    (рис P.53) Изменение свойств проекта для работы вне приложения браузера

    Добавим небольшой текст в MainPage.xaml, который будет отображать состояние приложения.

    <TextBlock 
      x:Name="textBox"
      Text="Приложение Silverlight. Версия 1" 
      HorizontalAlignment="Left"/>

    Запустим приложение и щелкнем правом клавишей мыши. Появится диалоговое окно, предлагающее установить приложение на компьютер.

    (рис P.54) Установка приложения Silverlight

    Нажимаем установить, затем выбираем места, в которые будут размещены ярлыки

    (рис P.55) Установка ярлыков

    Приложение сразу же запустится. Обратите внимание на появление ярлыков на рабочем столе и в меню программ. Теперь удалим его, щелкнув правой клавишей мыши внутри работающего приложения.

    (рис P.56) Удаление приложения

    Тоже самое можно сделать и в браузере. Приложение также будет удалено.

    Добавим в приложение код (файл MainPage.xaml.cs), позволяющий определить работает приложение в браузере или нет.

    public MainPage()
    {
        InitializeComponent();
        if (App.Current.IsRunningOutOfBrowser)
        { textBox.Text += ". Работа локально"; }
        else
        { textBox.Text += ". Работа в броузере"; }
    }

    Запускаем отладку и устанавливаем приложение локально, должно получиться:

    (рис P.57) Локальное и браузерное приложения

    Добавим кнопку, при нажатии на которую приложение будет установлено или удалено.

    <Button 
      x:Name="buttonInstall" 
      Click="Button_Click" 
      HorizontalAlignment="Left"/>

    И код в описание класса MainPage():

    if (App.Current.InstallState == 
        System.Windows.InstallState.Installed)
    {
        buttonInstall.Content = "Установлено";
    }
    else
    {
        buttonInstall.Content = " Не установлено. Установить";
    }
    App.Current.InstallStateChanged += 
        new EventHandler(Current_InstallStateChanged);

    В зависимости от состояния установки, изменяется надпись на кнопке. Кроме того, добавляется обработчик события изменения состояния установки:

    void Current_InstallStateChanged(object sender, EventArgs e)
    {
        if (App.Current.InstallState ==
            System.Windows.InstallState.Installed)
        {
            buttonInstall.Content = "Установлено";
        }
        else
        {
            buttonInstall.Content = " Не установлено. Установить";
        }
    }

    Обработчик событий нажатия кнопки:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (App.Current.InstallState ==
            System.Windows.InstallState.NotInstalled)
        {
            App.Current.Install();
        }            
    }

    После запуска должно быть:

    (рис P.58)

    При нажатии на кнопку приложение будет установлено.

    Обновление приложения

    Добавим кнопку и текст на страницу, а также, код в MainPage.xaml.cs, позволяющий отследить версию приложения и сразу же обновить его:

    <TextBlock 
      x:Name="textBox1"
      HorizontalAlignment="Left"/>
    <Button 
      x:Name="buttonUpdate"
      Content="Проверить обновления"
      Click="Button1_Click" 
      HorizontalAlignment="Left"/>
    
    private void Button1_Click(object sender, RoutedEventArgs e)
    {
        App.Current.CheckAndDownloadUpdateAsync();
        App.Current.CheckAndDownloadUpdateCompleted += 
            new CheckAndDownloadUpdateCompletedEventHandler
                (Current_CheckAndDownloadUpdateCompleted);
    }
    void Current_CheckAndDownloadUpdateCompleted
        (object sender, CheckAndDownloadUpdateCompletedEventArgs e)
    {
        if (e.UpdateAvailable)
        {
            textBox1.Text = "Установлены обновления. 
                           Перезапустите приложение";
        }
        else
        {
            textBox1.Text = "Новых обновлений нет";
        }
    }

    Запустим приложение в браузере и установим его, предварительно удалив старое. Затем изменим текст надписи в проекте на "Приложение Silverlight. Версия 2" и откомпилируем приложение 2-ой версии. Запустим приложение локально и нажмем на кнопку "Проверить обновления". Затем перезапустим его. Получим:

    (рис P.59) Проверка и установка обновлений

    При работе в браузере обновления, естественно, не проверяются, т.к. работает всегда свежая версия.

    Проверка подключения к Интернету

    Добавим в xaml файл текстовый блок:

    <TextBlock 
        x:Name="networkIndicator"
        HorizontalAlignment="Left"/>

    Он будет отражать состояние сети. В код добавим:

    using System.Net.NetworkInformation;

    и в конструктор класса MainPage():

    NetworkChange.NetworkAddressChanged += 
        new NetworkAddressChangedEventHandler
            (NetworkChange_NetworkAddressChanged);
    bool online = NetworkInterface.GetIsNetworkAvailable();
    networkIndicator.Text = online ?
        "ONLINE" : "OFFLINE";

    А также, обработчик события NetworkAddressChanged:

    void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
    {
        networkIndicator.Visibility =
            App.Current.IsRunningOutOfBrowser ?
            Visibility.Visible : Visibility.Collapsed;
        bool online = NetworkInterface.GetIsNetworkAvailable();
        networkIndicator.Text = online ?
            "ONLINE" : "OFFLINE";
    }

    Скомпилируем проект. Проверим обновления локального приложения и перезапустим его. Теперь откроем "Центр управления сетями и общим доступом" из панели управления Windows и откроем "Сетевые подключения". Теперь отключим действующее сетевое подключение:

    (рис P.60) Отключение сети

    Запустим приложение, должны увидеть следующее:

    (рис P.61) Работа локального приложения без сети

    Теперь, не закрывая, приложение включим сеть. Приложение через некоторое время определит, что сеть есть.

    (рис P.62) Работа локального приложения с сетью

    Заключение

    На данном практическом занятии мы создали Silverlight приложение, которое установили для работы локально. Рассмотрели вопросы обновления внебраузерных приложений и поддержку работы без подключения к интернету. Исходный код находится в файле

    Страницы:

    Прежде, чем приступить к созданию приложений Silverlight 3, необходимо убедиться, что все необходимые системные компоненты установлены. Для создания приложений необходимы:

  • Microsoft Silverlight 3 windows runtime (Silverlight.exe)
  • Microsoft Visual Studio 2008 + SP1, язык C#
  • Microsoft Silverlight 3 Tools for Microsoft Visual Studio 2008 SP1 (Silverlight3_Tools.exe)
  • Microsoft Silverlight 3 SDK (silverlight_sdk.exe)
  • Microsoft Silverlight 3 Toolkit July 2009 (Silverlight 3 Toolkit July 2009.msi)
  • Microsoft .NET RIA Services (RiaServices.msi)
  • Microsoft Internet Explorer 8
  • Microsoft Expression Encoder 3.0
  • Microsoft Internet Information Server 7.0
  • Microsoft IIS Media Services 3.0 (IISMedia32.msi)
  • Microsoft SQL Server 2008 + Client
  • База данных - пример AdventureWorks
  • Microsoft Expression 3.0 (Deep Zoom Composer, Expression Encoder)
  • Для выполнения практических работ по данному курсу от студента необходимо начальное знание языка C# и способов работы с Visual Studio.

    Создание простого приложения Silverlight

    Целью данного занятия является первое знакомство с Silverlight и создание простого приложения Silverlight

    Задание

    Создать новый проект Silverlight, разместить (захостить) приложение Silverlight в веб-приложении. Разместить стандартные элементы управления на странице Button, TextBox, TextBlock. Добавить управляющий код C#, который текст, введенный в TextBox, по нажатию кнопки, отображает в элементе TextBlock.

    Создание приложения по шаблону

    В Visual Studio создадим новый проект

    (рис P.1) Создание нового проекта Silverlight

    Выберем шаблон Silverlight Application и зададим имя проекта SilverlightApplication

    (рис P.2) Выбор шаблона для проекта Silverlight

    Приложение Silverlight должно быть размещено на веб-странице сайта. Создадим такой сайт. Это будет веб-приложение ASP.NET с названием SilverlightApplication.Web

    (рис P.3) Создание веб-приложения для размещения приложения Silverlight

    После окончания работы мастера, должно получиться следующее решение, содержащее 2 проекта SilverlightApplication и SilverlightApplication.Web.

    (рис P.4) Получившееся решение Silverlight

    Добавление элементов управления

    На страницу MainPage.xaml добавим элементы управления StackPanel и внутрь ее элементы TextBlock, TextBox и Button. Откроем MainPage.xaml и с панели ToolBox перетащим эти элементы внутрь контейнера Grid.

    <Grid x:Name="LayoutRoot">
        <StackPanel Height="480" Width="257">
            <TextBlock x:Name="textBlock"/>
            <TextBox x:Name="textBox" Text="Введите текст"/>
            <Button Content="Кнопка" Click="Button_Click"/>
        </StackPanel>
    </Grid>

    Для TextBlock зададим имя textBlock, для того, чтобы к нему можно было обращаться из кода C#. Для TextBox зададим имя textBox. Кроме того, textBox содержит текст Введите текст. Кнопка Button содержит текст Кнопка и при нажатии на нее будет вызван метод Button_Click кода C#. Этот метод выглядит так:

    private void Button_Click
         (object sender, System.Windows.RoutedEventArgs e)
    {
        textBlock.Text = textBox.Text;
    }

    Из примера видно как код xaml вызывает метод C# void Button_Click. И как код C# управляет свойствами элементов, описанных в коде xaml.

    Заключение

    В данном практическом занятии был создан проект Silverlight, размещен на веб сайте. Добавлены стандартные элементы управления. Осуществлен доступ к свойствам элементов управления, описанных в xaml, из кода и, наоборот, из xaml к коду C#.

    Создание элементов управления

    Целью данного практического занятия является создание пользовательских "богатых" элементов управления на основе стандартных. Здесь мы воспользуемся возможностью Silverlight по созданю шаблонов и стилей для стандартных элементов управления. Для выполнения задания необходима Visual Studio.

    Задание

    Создать пользовательские элементы управления Button, ComboBox и ListBox. Разместить элементы каждый на отдельной странице. Создать меню для навигации по страницам с пользовательскими элементами управления. В проекте SilverlightControls добавим папку \Controls, куда поместим пользовательские элементы управления. В папке Views разместим страницы с этими элементами.

    Меню

    Создаем проект Silverlight, как в разделе "Создание простого приложения Silverlight", согласно рис. P.1, рис. P.2 и рис. P.3. Называем его SilverlightControls. Разница лишь в том, что используем шаблон Silverlight Navigation Application.

    (рис P.5) Создание проекта по шаблону Silverlight Navigation Application

    Шаблон создаст 2 пункта меню в MainPage.xaml, таких как About и Home, мы его расширяем пунктами Button, ComboBox, ListBox:

    <Border x:Name="LinksBorder" 
            Style="{StaticResource LinksBorderStyle}">
        <StackPanel 
            x:Name="LinksStackPanel" 
            Style="{StaticResource LinksStackPanelStyle}">
            <HyperlinkButton 
                x:Name="Link1" 
                Style="{StaticResource LinkStyle}" 
                NavigateUri="/Home" 
                TargetName="ContentFrame" 
                Content="home"/>
            <Rectangle Style="{StaticResource DividerStyle}"/>                    
            <HyperlinkButton 
                x:Name="Link2" Style="{StaticResource LinkStyle}" 
                NavigateUri="/About" 
                TargetName="ContentFrame" 
                Content="about"/>                    
            <Rectangle Style="{StaticResource DividerStyle}"/>                    
            <HyperlinkButton 
                x:Name="Link3" 
                Style="{StaticResource LinkStyle}"                                      
                NavigateUri="/ButtonPage" 
                TargetName="ContentFrame" 
                Content="Button"/>
            <Rectangle Style="{StaticResource DividerStyle}"/>                    
            <HyperlinkButton 
                x:Name="Link4" 
                Style="{StaticResource LinkStyle}" 
                NavigateUri="/ComboBoxPage" 
                TargetName="ContentFrame" 
                Content="ComboBox"/>
            <Rectangle Style="{StaticResource DividerStyle}"/>                    
            <HyperlinkButton 
                x:Name="Link5" 
                Style="{StaticResource LinkStyle}" 
                NavigateUri="/ListBoxPage" 
                TargetName="ContentFrame" 
                Content="ListBox"/>
        </StackPanel>
    </Border>

    Далее необходимо создать страницы и сами элементы управления.

    Элемент Button

    Добавляем новый пользовательский элемент управления ButtonControl.xaml (Add/New Item). Размещаем его в каталоге \Controls. Туда же добавим рисунки 4.jpg и SL.png.

    (рис P.6) Создание пользовательского элемента управления Button

    Добавим стандартный элемент Button

    <Button 
        x:Name="button1"             
        Content="Button1" 
        Click="Button_Click"
        Style="{StaticResource ImageButton}" 
        HorizontalAlignment="Left" Width="77"/>

    и улучшим его внешний вид с помощью стиля:

    <UserControl.Resources>
       <Style x:Key="TextBlockStyle" TargetType="TextBlock"> 
          <Setter Property="FontFamily" Value="Comic Sans Ms"/>
          <Setter Property="Text" Value="Click!"/>
          <Setter Property="Foreground" Value="MediumBlue"/>
          <Setter Property="FontSize" Value="15"/>
       </Style>
       <Style x:Key="ImageButton" TargetType="Button">
          <Setter Property="Template">
             <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Button>
                       <StackPanel Orientation="Vertical">
                          <Image 
                              Source="SL.png" 
                              Height="65" 
                              Width="65" 
                              Stretch="Fill"/>
                          <TextBlock 
                              Style="{StaticResource TextBlockStyle}" 
                              HorizontalAlignment="Center"/>
                       </StackPanel>
                    </Button>
                </ControlTemplate>
             </Setter.Value>
          </Setter>
       </Style>
    </UserControl.Resources>
  • Т.е. кнопка будет состоять из кнопки <Button/>. Эта кнопка является контейнером для <StackPanel/>, которая в свою очередь содержит <Image/> и <TextBlock/>. К текстовому блоку привязан стиль TextBlockStyle. К самой кнопке привязан стиль ImageButton.
  • Добавляем страницу ButtonPage.xaml для размещения этого элемента, страницу поместим в каталог \Views проекта.

    (рис P.7) Создание страницы для элемента управления Button

    На странице ButtonPage.xaml добавляем пространство имен класса SilverlightControls:

    xmlns:local="clr-namespace:SilverlightControls"

    и в сетку страницы сам элемент управления Button:

    <local:ButtonControl 
        VerticalAlignment="Top" 
        HorizontalAlignment="Center"/>

    После запуска мы получим:

    (рис P.8) Внешний вид пользовательского элемента управления Button

    Элемент ComboBox

    Добавляем новый пользовательский элемент управления ComboBoxControl.xaml (Add/New Item). Размещаем его в каталоге \Controls. Туда же добавим рисунки 1.jpg, 2.jpg и 3.jpg.

    (рис P.9) Создание пользовательского элемента управления ComboBox

    Добавим стандартный элемент ComboBox:

    <ComboBox 
       Margin="37,0,0,119" 
       Height="22" 
       VerticalAlignment="Bottom" 
       HorizontalAlignment="Left" 
       Width="65"/>

    Добавим три элемента, улучшим вид каждого элемента, с помощью шаблона:

    <ComboBox 
        Margin="37,0,0,119" 
        Height="22" 
        VerticalAlignment="Top" 
        HorizontalAlignment="Left" 
        Width="65">
        <ComboBoxItem>
            <StackPanel Orientation="Horizontal">
                <Image 
                    Height="100" 
                    Width="100" 
                    Source="1.jpg"/>
                <TextBlock 
                    Text="Ferrari F430" 
                    HorizontalAlignment="Right" 
                    VerticalAlignment="Center"/>
            </StackPanel>
        </ComboBoxItem>
        <ComboBoxItem>
            <StackPanel Orientation="Horizontal">
                <Image 
                    Height="100" 
                    Width="100" 
                    Source="2.jpg"/>
                <TextBlock 
                    Text="Fisker Karma" 
                    HorizontalAlignment="Right" 
                    VerticalAlignment="Center"/>
            </StackPanel>
        </ComboBoxItem>
        <ComboBoxItem>
            <StackPanel Orientation="Horizontal">
                <Image 
                    Height="100" 
                    Width="100" 
                    Source="3.jpg"/>
                <TextBlock 
                    Text="Lamborghini Murcielago LP 640" 
                    HorizontalAlignment="Right" 
                    VerticalAlignment="Center"/>
            </StackPanel>
        </ComboBoxItem>
    </ComboBox>

    Каждый пункт списка содержит вложенную панель <StackPanel/>, в которую вложены элементы <Image/> и <TextBlock/>.

    Добавляем страницу ComboBoxPage.xaml для размещения этого элемента, страницу поместим в каталог \Views проекта.

    (рис P.10) Создание страницы для элемента управления ComboBox

    На странице ComboBoxPage.xaml добавляем пространство имен класса SilverlightControls:

    xmlns:local="clr-namespace:SilverlightControls"

    и в сетку страницы сам элемент управления ComboBox:

    <local:ComboBoxControl 
        VerticalAlignment="Top" 
        HorizontalAlignment="Center"/>

    После компиляции проекта мы увидим ниспадающий список автомобилей с их изображениями:

    (рис P.11) Внешний вид пользовательского элемента управления ComboBox

    Элемент ListBox

    Добавляем новый пользовательский элемент управления ListBoxControl.xaml (Add/New Item). Размещаем его в каталоге \Controls.

    (рис P.12) Создание пользовательского элемента управления ListBox

    Добавим стандартный элемент ListBox:

    <ListBox 
        x:Name="_listbox"
        Margin="0,0,-2,0" 
        HorizontalAlignment="Center" 
        VerticalAlignment="Bottom">
        Width="229" 
        Height="230"
        <StackPanel Orientation="Horizontal">
            <Image Height="100" Width="100" Source="1.jpg"/>
            <TextBlock 
                Text="Ferrari F430" 
                HorizontalAlignment="Right" 
                VerticalAlignment="Center"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Image Height="100" Width="100" Source="2.jpg"/>
            <TextBlock 
                Text="Fisker Karma" 
                HorizontalAlignment="Right" 
                VerticalAlignment="Center"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Image Height="100" Width="100" Source="3.jpg"/>
            <TextBlock 
                Text="Lamborghini Murcielago LP 640" 
                HorizontalAlignment="Right" 
                VerticalAlignment="Center"/>
        </StackPanel>
    </ListBox>

    И добавим 3 пункта, с помощью шаблона. Шаблон содержит элемент <StackPanel/>, который содержит рисунок <Image/> и текст <TextBlock/>.

    Добавляем страницу ListBoxPage.xaml для размещения этого элемента, страницу поместим в каталог \Views проекта.

    (рис P.13) Создание страницы для элемента управления ListBox

    На странице ListBoxPage.xaml добавляем пространство имен класса SilverlightControls:

    xmlns:local="clr-namespace:SilverlightControls"

    и в сетку страницы сам элемент управления ListBox:

    <local:ListBoxControl 
        VerticalAlignment="Top" 
        HorizontalAlignment="Center"/>

    После компиляции проекта мы увидим список автомобилей с их изображениями:

    (рис P.14) Внешний вид пользовательского элемента управления ListBox

    Заключение

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

    Работа с базами данных

    На данном занятии должно быть разработано приложение Silverlight, которое соединяется с базой данных и работают с таблицами. Основные способы это:

  • Веб-сервисы: SOAP, ASP.NET web services (ASMX), WCF services, REST, .NET RIA Services.
  • Сокеты: network socket communication
  • Сокеты в данном практическом занятии рассматриваться не будут, т.к. это довольно сложный и устаревший способ доступа к данным. В данном примере рассмотрим RIA сервис, как наиболее изящный и простой способ подключения. Для работы с таблицами будем использовать элементы управления DataGrid и DataForm.

    Для выполнения задания необходимы Visual Studio, SQL Server+Client.

    Задание

    Разработать приложение Silverlight соединяющееся с базой данных AdventureWorks (база данных - пример) и извлекающее данные из таблицы Product. Данная база работает под управлением СУБД MS SQL Server 2008. Задача состоит из этапов:

  • Создание нового проекта Silverlight
  • Создание нового проекта ASP.NET
  • Создание модели данных в проекте ASP.NET
  • Создание сервиса для отображения модели данных ASP.NET
  • Создание элементов управления в проекте Silverlight
  • DataGrid - табличный элемент управления для отображения содержимого таблицы Product
  • DataForm - элемент управления для отображения и редактирования содержимого одной строки таблицы Product для выбранного в DataGrid продукта
  • TextBlock - для подписей
  • Button - элемент управления для сохранения и удаления строк.
  • Асинхронный запрос к веб-сервису для получения содержимого Product
  • Отображение данных списков в соответствующих элементах управления
  • Сортировка, группировка, постраничный показ, фильтрация строк в DataGrid.
  • Редактирование данных в DataForm
  • Для выполнения данного задания необходимо установленное программное обеспечение (см. раздел 1 "Введение"), а также, работающая СУБД SQL Server 2008 с базой данных AdventureWorks (прилагается файл с базой) и клиентская часть данной СУБД. Необходимо отметить значение .NET RIA Services для выполнения этого задания. Данная служба является опцией Internet Information Server и устанавливается на веб-сервер.

    Описание таблиц Product

    Ниже приведена структура таблицы Product.

    (рис P.15) Описание таблицы Product

    Создание приложения

    В Visual Studio 2008 создаем новый проект Silverlight под названием DatabaseSilverlightApplication, по шаблону Silverlight Application.

    (рис P.16) Создание проекта DatabaseSilverlightApplication

    Во время создания укажите привязку к .NET RIA Services, которые будут использованы для получения более высокого функционала приложения легким способом.

    (рис 4.3) Добавление расширений .NET RIA Services

    После окончания работы мастера будет создано решение, состоящее из двух проектов:

    (рис P.17) Проекты DatabaseSilverlightApplication и DatabaseSilverlightApplication.Web

    Далее открываем MainPage.xaml и MainPage.xaml.cs и работаем с ними.

    Создание источника данных

    Для того чтобы отображать данные на клиенте, необходимо создать источник данных DataContext в веб-приложении DatabaseSilverlightApplication.Web. Это делается в два этапа. Сначала создается модель данных, затем веб-сервис.

    Чтобы создать модель, добавляем новый пункт new item и выбираем ADO.NET Entity Data Model.

    (рис P.18) Добавление ADO.NET Entity Data Model

    Выбираем автоматическую генерацию модели из базы данных

    (рис P.19) Генерация модели из базы данных

    Создаем подключение веб-приложения к базе данных. Генерируем новое соединение, выбираем имя сервера и имя базы данных, тестируем соединение.

    (рис P.20) Создание подключения к базе данных

    После того, как мастер подключится к базе данных и прочитает там список доступных объектов, выбираем нужная таблица Product.

    (рис P.21) Выбор объектов базы данных для создания сущностей

    Теперь необходимо создать веб-сервис. Для начал нужно построить (build) веб-приложение. Для того чтобы, модель отразилась в dll и была видна для мастера создания сервиса. Добавляем пункт new item и выбираем Domain Service Class

    (рис P.22) Добавление веб-сервиса Domain Service Class

    Затем мастер предложит выбрать таблицы для отражения их в веб-сервисе.

    (рис 4.10) Добавление сущностей в веб-сервис

    Выбираем все и указываем возможность редактирования. Мастер сгенерирует все необходимые для этого методы. GetProduct() - для выборки данных, InsertProduct(Product product) - для добавления строки, UpdateProduct(Product currentProduct) - для модификации и DeleteProduct(Product product) - для удаления.

    (рис P.23) Методы для работы с сущностями

    Теперь переходим непосредственно к проекту DatabaseSilverlightApplication.

    Вывод данных таблицы

    Добавляем на страницу MainPage.xaml элемент управления DataGrid. Он будет служить для отображения данных таблицы Product. Его название productGrid, он будет получать данные из источника данных ProductsData. Выводить мы будем только выбранные поля Color, Name, ModifiedDate, ProductNumber, ListPrice, Weight, WeightUnitMeasureCode, MakeFlag, FinishedGoodsFlag, ProductLine, Size, SizeUnitMeasureCode и StandardCost. Значение свойства AutoGenerateColumns надо задать False. Если этого не сделать, тогда будут выведены все поля плюс эти поля таблицы Product.

    <data:DataGrid 
        x:Name="productGrid" 
        Margin="0,22,318,0"
        ItemsSource="{Binding Data, ElementName=ProductsData}" 
        AutoGenerateColumns="False" >
        <data:DataGrid.Columns>
            <data:DataGridTextColumn
            Header="Color"
            Binding="{Binding Color}"/>
            <data:DataGridTextColumn
            Header="Name"
            Binding="{Binding Name}"/>
            <data:DataGridTextColumn
            Header="Modified"
            Binding="{Binding ModifiedDate}"/>
            <data:DataGridTextColumn
            Header="ProductNumber"
            Binding="{Binding ProductNumber}"/>
            <data:DataGridTextColumn
            Header="Price"
            Binding="{Binding ListPrice}"/>
            <data:DataGridTextColumn
            Header="Weight"
            Binding="{Binding Weight}"/>
            <data:DataGridTextColumn
            Header="Unit"
            Binding="{Binding WeightUnitMeasureCode}"/>
            <data:DataGridCheckBoxColumn
            Header="Make"
            Binding="{Binding MakeFlag}"/>
            <data:DataGridCheckBoxColumn
            Header="Finished"
            Binding="{Binding FinishedGoodsFlag}"/>
            <data:DataGridTextColumn
            Header="ProductLine"
            Binding="{Binding ProductLine}"/>
            <data:DataGridTextColumn
            Header="Size"
            Binding="{Binding Size}"/>
            <data:DataGridTextColumn
            Header="Unit"
            Binding="{Binding SizeUnitMeasureCode}"/>
            <data:DataGridTextColumn
            Header="StandardCost"
            Binding="{Binding StandardCost}"/>
        </data:DataGrid.Columns>
    </data:DataGrid>

    Чтобы создать источник данных ProductsData, добавляем ссылку reference на библиотеку System.Windows.Ria.Controls:

    (рис P.24) Создание ссылки для элементов управления RIA

    На страницу MainPage.xaml добавляем:

    xmlns:ria="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls"
    xmlns:riaData="clr-namespace:System.Windows.Data;assembly=System.Windows.Ria.Controls"

    Добавляем источник данных ProductsData на страницу:

    <UserControl.Resources> 
        <ria:DomainDataSource 
            x:Name="ProductsData" 
            AutoLoad="True"
            QueryName="GetProductQuery">
            <ria:DomainDataSource.DomainContext>
                <DatabaseSilverlightApplication_Web:ProductContext/>
            </ria:DomainDataSource.DomainContext>            
        </ria:DomainDataSource> 
    </UserControl.Resources>

    Здесь указан метод GetProductQuery, возвращающий данные из базы и контекст, в который эти данные загружаются ProductContext. В атрибуты элемента DataGrid вставляем привязку к контексту ProductsData:

    <data:DataGrid 
        ItemsSource="{Binding Data, ElementName=ProductsData}"

    Теперь можно запустить приложение:

    (рис P.25) Отображение данных таблицы

    Теперь добавим интересный элемент управления "бегунок" ActivityControl.dll add reference. Данный элемент не является продуктом Microsoft и скачивается отдельно http://www.davidpoll.com/Download/ActivityControl9-14.zip

    (рис P.26) Создание ссылки для элемента управления ActivityControl

    Обновим пространство имен страницы MainPage.xaml

    xmlns:activity="clr-namespace:System.Windows.Controls;assembly=ActivityControl"

    И добавим этот элемент на страницу, поместив описание DataGrid внутрь этого элемента:

    <activity:Activity 
    	IsActive="{Binding IsBusy, ElementName=ProductsData}">
        <data:DataGrid

    Видим, что во время загрузки данных индикатор загрузки работает, а после исчезает:

    (рис P.27) Элемент управления ActivityControl

    Сортировка

    Сортировка строк осуществляется методами самого элемента DataGrid. Свойство задается в описании DataGrid.

    CanUserSortColumns="True"

    По умолчанию значение свойства - True. По нажатию на поле осуществляется сортировка по возрастанию, при повторном нажатии - по убыванию.

    Постраничный вывод

    Теперь добавим элемент, который будет осуществлять Paging, т.е. постраничный вывод данных, разбитие их на страницы. Для этого служит элемент DataPager. Добавляем его на страницу:

    <data:DataPager
        Source="{Binding Data, ElementName=ProductsData}"                        
        PageSize="10"

    Привязываем этот элемент к данным ProductsData, так же как привязывали данные к DataGrid.

    Группировка

    Теперь добавим возможность группировки данных. Это можно сделать в коде:

    public MainPage()
    {
        InitializeComponent();
        ProductsData.GroupDescriptors.Add(new GroupDescriptor("Color"));
    }

    Можно в описании xaml, добавив как свойство GroupDescriptor из набора GroupDescriptors источника данных:

    <ria:DomainDataSource 
     …
        <ria:DomainDataSource.GroupDescriptors>
            < riaData:GroupDescriptor PropertyPath="Color"/>            
        </ria:DomainDataSource.GroupDescriptors>
    </ria:DomainDataSource>

    Полей для группировки может быть несколько:

    <riaData:GroupDescriptor PropertyPath="ProductLine"/>
    <riaData:GroupDescriptor PropertyPath="Color"/>
    
    ProductsData.GroupDescriptors.Add(new GroupDescriptor("ProductLine"));
    ProductsData.GroupDescriptors.Add(new GroupDescriptor("Color"));

    Это будет выглядеть так:

    (рис P.28) Группировка строк в DataGrid

    Фильтрация

    Добавим на страницу xaml поле для ввода фильтра FilterText:

    <TextBlock Text="Filter Name:"/>
    <TextBox x:Name="FilterText" TextChanged="FilterText_TextChanged"/>

    В описание источника данных добавляем описание фильтра:

    <ria:DomainDataSource 
        <ria:DomainDataSource.FilterDescriptors>
            <riaData:FilterDescriptorCollection>
                <riaData:FilterDescriptor 
                    PropertyPath="Name" 
                    Operator="Contains">
                    <riaData:ControlParameter 
                        ControlName="Filter" 
                        PropertyName="Text" 
                        RefreshEventName="TextChanged" />
                </riaData:FilterDescriptor>
            </riaData:FilterDescriptorCollection>
        </ria:DomainDataSource.FilterDescriptors>
    </ria:DomainDataSource>

    Обратите внимание на атрибут Operator. RIA сервисы предлагают дополнительные условия фильтрации:

    (рис P.29) Условия фильтрации

    Либо в коде добавляем обработчик событий:

    private void FilterText_TextChanged
        (object sender, System.Windows.Controls.TextChangedEventArgs e)
    {
        FilterDescriptorCollection fcollection = 
            new FilterDescriptorCollection();
        FilterDescriptor fdescr = 
            new FilterDescriptor
                ("Name", FilterOperator.Contains, FilterText.Text);
        fcollection.Add(fdescr);
        ProductsData.FilterDescriptors = fcollection;
    }

    Получаем работающий фильтр:

    (рис P.30) Фильтрация строк в DataGrid

    Теперь перейдем к изменению данных в таблице. Добавим в MainPage.xaml элемент управления DataForm:

    <dataFormToolkit:DataForm 
        x:Name="productEditForm"             
        CurrentItem="{Binding 
                      ElementName=productGrid, Path=SelectedItem}"
        AutoCommit="False"
        AutoEdit="True"
        Header="Details"/>

    Как видно из описания, он привязан к другому элементу productGrid, и при выборе строки SelectedItem отображает содержимое всей строки таблицы базы данных.

    Получается приложение такого вида:

    (рис P.31) Детализация с помощью элемента управления DataForm

    Изменения данных (было Blue, стало Green ) отслеживаются этим элементом. Видно появление звездочки вверху элемента, кнопки OK и отмена активизировались и появились изменения в DataGrid. После нажатия кнопки OK изменения появятся и в источнике данных и. Можно тоже самое сделать с помощью кода. Для манипуляции с данными к этому добавим панель с кнопками, код C# и изменим описание DataForm. Добавим в DataForm:

    <dataFormToolkit:DataForm 
        CommandButtonsVisibility="None"

    Добавим панель с кнопкой сохранения изменений:

    <StackPanel Orientation="Horizontal" 
                Height="23" 
                VerticalAlignment="Bottom">
        <Button Content="Save changes" 
                Click="Button_Click"/>
    </StackPanel>

    И метод в код страницы:

    private void Button_Click
        (object sender, RoutedEventArgs e)
    {
        productEditForm.CommitEdit();
        ProductsData.SubmitChanges();
    }

    Для удаления строки добавим кнопку удалить со следующим описанием:

    <Button Content="Delete" 
            Click="ButtonDelete_Click"/>

    И код C#:

    private void ButtonDelete_Click(object sender, RoutedEventArgs e)
    {
        productEditForm.CommitEdit();
        productEditForm.DeleteItem();
        ProductsData.SubmitChanges();
    }

    Заключение

    На данном практическом занятии мы рассмотрели пример работы с базой данных MS SQL 2008, с таблицами, научились делать выборку, сортировать, группировать и фильтровать строки, удалять, изменять данные таблиц, а также, оценили роль .NET RIA Services, значительно упрощающих разработку приложения Silverlight. Исходный код данного примера приведен в файле DataBase.zip.

    Работа с веб сервисами

    Задание

    Задачей данного занятия является использование веб-сервиса Аэрофлота для создания приложения Silverlight, дающего возможность просматривать авиа рейсы прибывающие и вылетающие для заданного аэропорта мира и на заданную дату. Задача состоит из этапов:

  • Создание нового проекта Silverlight
  • Подключение к веб-сервису из приложения Silverlight по адресу в Интернете http://webservices.aeroflot.ru/flightstatus.asmx?WSDL
  • Создание элементов управления
  • ComboBox - для отображения списка аэропортов
  • ComboBox - для отображения списка дат, на которые доступна информация о рейсах
  • Button - кнопка начала поиска
  • DataGrid - табличный элемент управления для отображения вылетающих рейсов
  • DataGrid - табличный элемент управления для отображения прибывающих рейсов
  • TextBlock - для подписей к DataGrid
  • Асинхронный запрос к веб-сервису для получения списка аэропортов
  • Асинхронный запрос к веб-сервису для получения списка дат
  • Асинхронный запрос к веб-сервису для получения списка вылетающих рейсов
  • Асинхронный запрос к веб-сервису для получения списка прибывающих рейсов
  • Отображение данных списков в соответствующих элементах управления
  • Для выполнения данной работы необходимо установленное программное обеспечение (см. раздел 1 "Введение"), а также, доступ в Интернет.

    Описание веб-сервиса "Справка о рейсе/Табло аэропортов"

    Данный сервис позволяет получать информацию о текущем состоянии рейсов, просматривать табло аэропортов. Сервис предоставляет следующий набор функций:

  • AirportList - список аэропортов
  • AirportInfo - информация об аэропорте по его коду
  • DateList - список дат, за которые есть информация
  • Arrival/Departure - информация о прибытии/отправлении рейсов
  • FlightSearch - поиск рейса по номеру
  • FlightInfo - подробная информация о текущем состоянии рейса (по ключу, полученному в результате вызова Arrival/Departure/FlightSearch ).
  • AirportList - Список аэропортов. Возвращается список структур, состоящих из следующих полей:

  • city - город
  • name - название аэропорта
  • code - код аэропорта
  • AirportInfo - Информация об аэропорте. Входные параметры:

  • code - код аэропорта
  • Возвращается структура, состоящая из следующих полей:

  • city - город
  • name - название аэропорта
  • code - код аэропорта
  • Arrival - Табло прилета. Входные параметры:

  • code - код аэропорта
  • date - дата
  • order_field - поле (' airport ', ' sched ', ' plan ', ' company ', ' flight_no '), по которому идет сортировка
  • order - направление сортировки (' desc ', ' asc ')
  • Возвращается список структур, состоящих из следующих полей:

  • flt_pk - код рейса
  • company - код авиакомпании
  • flight_no - номер рейса
  • airport_inter - название промежуточного аэропорта
  • airport - название аэропорта отправления
  • sched - время прибытия по расписанию
  • plan - планируемое время прибытия
  • fact - фактическое время прибытия
  • calc - расчетное время прибытия
  • estimated arrival time
  • real - время посадки
  • union_flight_no - номер, объединенного рейса
  • status - статус рейса
  • DateList - Список дат, за которые есть данные в системе

    Departure - Табло вылета. Входные параметры:

  • code - код аэропорта
  • date - дата
  • order_field - поле (' airport ', ' sched ', ' plan ', ' company ', ' flight_no '), по которому идет сортировка
  • order - направление сортировки (' desc ', ' asc ')
  • Возвращается список структур, состоящих из следующих полей:

  • flt_pk - код рейса
  • company - код авиакомпании
  • flight_no - номер рейса
  • airport_inter - название промежуточного аэропорта
  • airport - название аеропорта назначения
  • sched - время вылета по расписанию
  • plan - планируемое время вылета
  • fact - фактическое время вылета
  • real - время взлета
  • union_flight_no - номер, объединенного рейса
  • status - статус рейса
  • is_check - признак регистрации ( 1 - идет, 0 - нет)
  • is_board - признак посадки в самолет ( 1 - идет, 0 - нет)
  • FlightInfo - Подробная информация о рейсе. Входные параметры:

  • flt_pk - код рейса
  • Возвращается список структур, состоящих из следующих полей:

  • company - код авиакомпании
  • flight_no - номер рейса
  • flight_type - тип рейса
  • aircraft_type - тип самолета
  • bort - номер самолета (борта)
  • seats_f - количество мест первого класса
  • seats_c - количество мест бизнес-класса
  • seats_y - количество мест эконом-класса
  • sched_dep - время вылета по расписанию
  • sched_arr - время прибытия по расписанию
  • plan_dep - планируемое время вылета
  • plan_arr - планируемое время прибытия
  • fact_dep - фактическое время вылета
  • fact_arr - фактическое время прибытия
  • real_dep - время взлета
  • real_arr - время посадки
  • calc - расчетное время прибытия
  • status - статус рейса
  • city_dep - город отправления
  • airport_dep - название аеропорта отправления
  • code_dep - код аэропорта отправления
  • terminal_dep - номер терминала аэропорта отправления
  • city_arr - город назначения
  • airport_arr - название аеропорта назначения
  • code_arr - код аэропорта назначения
  • terminal_arr - номер терминала аэропорта назначения
  • FlightSearch - Поиск рейсов. Входные параметры:

  • flight_no - номер рейса
  • flight number
  • Возвращается список структур, состоящих из следующих полей:

  • flt_pk - код рейса
  • company - код авиакомпании
  • flight_no - номер рейса
  • airport_dep - название аэропорта отправления
  • airport_inter - название промежуточного аэропорта
  • airport_arr - название аеропорта назначения
  • sched_dep - время вылета по расписанию
  • Адрес данного веб-сервиса:

    http://webservices.aeroflot.ru/flightstatus.asmx?WSDL

    Создание приложения Silverlight и подключение к веб-сервису

    Теперь создадим приложение Silverlight, а также веб-приложение для отображения приложения Silverlight. Для этого последовательно выполняем шаги, изображенные на рис.5.1 - рис. 5.4. В Visual Studio 2008 создаем новый проект, указываем шаблон "Silverlight Application", вводим название и каталог будущего проекта.

    (рис P.32) Создание проекта Silverlight

    Во время работы мастера отвечаем на вопрос, где будет "хоститься" новое приложение. Указываем, что на новом веб-сервере. Visual Studio создаст по шаблону простейшее веб-приложение ASP.NET и разместит на его странице необходимые ссылки на приложение Silverlight.

    (рис P.33) Создание веб проекта

    В результате работы мастера Visual Studio будет создано решение (см. рис.5.3)

    (рис P.34) Внешний вид нового проекта

    Далее кликаем на проекте Silverlight правой клавишей мыши и выбираем "Add Service Reference". В поле "Address" вводим адрес веб-сервиса в интернете: http://webservices.aeroflot.ru/flightstatus.asmx?WSDL. Сразу увидим контракт, предлагаемый веб-сервисом. Вводим пространство имен для данной ссылки.

    (рис P.35) Подключение к веб-сервису Аэрофлота

    Работа с веб-сервисом

    После подключения к веб-сервису Аэрофлота создаем интерфейс для посылки запросов к нему и отображения результата. Теперь необходимо изменить содержимое файла MainPage.xaml, как показано ниже:

    <UserControl
        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" 
        mc:Ignorable="d" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" 
        xmlns:dataFormToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit" 
        xmlns:AEROSilverlightApplication_FlightStatusReference="clr-namespace:AEROSilverlightApplication.FlightStatusReference" 
        xmlns:local="clr-namespace:AEROSilverlightApplication" 
        x:Class="AEROSilverlightApplication.MainPage"
        d:DesignWidth="640" d:DesignHeight="480">
        <StackPanel x:Name="LayoutRoot" >
            	<ComboBox
            		x:Name="airoportListBox"
    			Width="200" 
                    	HorizontalAlignment="Left" 
                    	SelectedIndex="0">
            		<ComboBoxItem Content="Список аэропортов"/>
            	</ComboBox>
            	<ComboBox                                    
            		x:Name="dateListBox" 
    			Width="200" 
               	HorizontalAlignment="Left" 
                    	SelectedIndex="0">
            		<ComboBoxItem Content="Доступные даты"/>
            	</ComboBox>
            	<Button 
            		Click="Button_Click" 
            		Content="Искать рейсы"
    			Width="200" 
                    	HorizontalAlignment="Left"/>
            	<TextBlock Text="Отправление"/>
            	<data:DataGrid x:Name="departureListGrid" 
                               HorizontalAlignment="Left"/>
            	<TextBlock Text="Прибытие"/>
            	<data:DataGrid x:Name="arrivalListGrid" 
                               HorizontalAlignment="Left"/>
        </StackPanel>
    </UserControl>

    В данном файле описаны 2 элемента управления ComboBox. airoportListBox - содержит список аэропортов всего мира, dateListBox - список дат, на которые имеются данные о рейсах. Элементы управления TextBlock - соответствующие надписи для элементов DataGrid. Эти элементы отображают список рейсов прибывающих ( arrivalListGrid ) и вылетающих ( departureListGrid ) в заданный день с выбранного аэропорта. Имеется кнопка Button, при нажатия которой (событие Button_Click ) выполнится обращение к веб-сервису, а результат будет занесен в элементы DataGrid.

    После этого переходим к редактированию кода страница code-behind. Содержимое файла MainPage.xaml.cs приведено ниже:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using AEROSilverlightApplication.FlightStatusReference;
    using System.Collections.ObjectModel;
    using System.Collections;
    
    namespace AEROSilverlightApplication
    {
        public partial class MainPage : UserControl
        {
            public FlightStatusSoapClient flightStatusClient;
            public MainPage()
            {
                InitializeComponent();            
                flightStatusClient = 
                    new FlightStatusSoapClient();
                flightStatusClient.AirportListCompleted += 
                    new EventHandler<AirportListCompletedEventArgs>
                        (flightStatusClient_AirportListCompleted);
                flightStatusClient.DateListCompleted += 
                    new EventHandler<DateListCompletedEventArgs>
                        (flightStatusClient_DateListCompleted);
                flightStatusClient.AirportListAsync();
                flightStatusClient.DateListAsync();
            }
            private void Button_Click
                (object sender, RoutedEventArgs e)
            {
                string code = 
                    airoportListBox.SelectedItem.ToString().Substring(0, 3);
                string date = 
                    dateListBox.SelectedItem.ToString();
                flightStatusClient.DepartureCompleted += 
                    new EventHandler<DepartureCompletedEventArgs>
                        (flightStatusClient_DepartureCompleted);
                flightStatusClient.ArrivalCompleted += 
                    new EventHandler<ArrivalCompletedEventArgs>
                        (flightStatusClient_ArrivalCompleted);
                flightStatusClient.DepartureAsync(code, date, "sched", "asc");
                flightStatusClient.ArrivalAsync(code, date, "sched", "asc");
            }
            void flightStatusClient_ArrivalCompleted
                (object sender, ArrivalCompletedEventArgs e)
            {
                arrivalListGrid.ItemsSource = e.Result;
            }
            void flightStatusClient_DepartureCompleted
                (object sender, DepartureCompletedEventArgs e)
            {
                departureListGrid.ItemsSource = e.Result;
            }
            void flightStatusClient_DateListCompleted
                (object sender, DateListCompletedEventArgs e)
            {
                IEnumerable<DateTime> query = 
                    e.Result.OrderBy(date => date);
                IEnumerable<string> query1 = 
                    query.Select<DateTime, string>
                    (date => date.ToShortDateString());
                dateListBox.Items.Clear();
                dateListBox.ItemsSource = query1;
            }
            void flightStatusClient_AirportListCompleted
                (object sender, AirportListCompletedEventArgs e)
            {
                IEnumerable<Airport> query = 
                    e.Result.OrderBy(Airport => Airport.city);
                IEnumerable<string> query1 = 
                    query.Select<Airport, string>
                    (Airport => Airport.code + ' ' + Airport.city);
                airoportListBox.Items.Clear();
                airoportListBox.ItemsSource = query1;
            }
        }
    }

    Рассмотрим код. Конструктор класса MainPage(). Вначале при загрузке страницы создается экземпляр класса FlightStatusSoapClient. Он необходим для асинхронного вызова данных. Затем асинхронно вызываем методы этого класса AirportListAsync() и DateListAsync(), для того, чтобы получить список аэропортов и дат. Добавляем обработчики событий AirportListCompleted и DateListCompleted, для того чтобы принять и обработать полученные данные.

    После того, как пользователь выбрал дату и аэропорт из списка, например, аэропорт Вены и 8 октября 2009 г, и нажал кнопку поиска, при срабатывают события Button_Click, заданное в xaml файле Click="Button_Click".

    После этого будут вызваны асинхронные методы, получающие от веб-сервиса списки рейсов прибывающих и вылетающих.

    После завершения отладки приложения можно увидеть результат (см. рис.P.36)

    (рис P.36) Работа приложения с веб-сервисом

    Выбран аэропорт Вены, дата 8 октября 2009 г. Мы видим 2 рейса отправляющихся в Москву и два рейса прибывающих из Москвы в этот день.

    Заключение

    В данном разделе рассмотрен пример создания приложения для работы с веб-сервисом Аэрофлота. Исходный код рассмотренного решения расположен в каталоге AERO.

    Smooth Streaming и Expression Encoder

    Целью данного практического занятия является изучение средства Expression Encoder из состава Microsoft Expression 3.0.

    Задание

    Разработать приложение Silverlight, приложение должно содержать медиаплеер, медиаплеер должен воспроизводить фильм, используя технологию Smooth Streaming. Одним из козырей этой технологии является поддержка различных битрейтов для видео. На данном занятии необходимо создать видеофайлы со следующими битрейтами: 2500, 1000 и 200 кбит/с. Для выполнения задания необходимы Microsoft Expression Encoder и Visual Studio. Кроме того, необходим сервер Internet Information Server и установлена служба IIS Media Services, которая является дополнением к IIS.

    Создание медиафайлов

    В среде Expression Encoder импортировать медифайл "Asteroid Impact_mpeg4.avi" для обработки. Характеристики данного файла: разрешение - HD 1280x720, соотношение сторон - 16:9, частота кадров - 29,97, видео кодек - mpeg4, битрейт видео - 2500, аудио кодек - mp3, битрейт аудио - 192, формат файла (контейнер) - AVI. Во время импорт Expression Encoder анализирует все свойства видео.

    (рис P.37) Импорт видеофайла в Expression Encoder

    После завершения анализа будут показаны характеристики файла и потока внизу на панели управления "Media content".

    (рис P.38) Параметры видеофайла в Expression Encoder

    Теперь необходимо создать набор выходных файлов с заданным битрейтом. Значение свойства "Output Format" задаем "IIS Smooth Streaming".

    (рис P.39) Выбор выходного формата видео

    Заключение

    Исходный код находится в файле SmoothStreaming.zip.

    Deep Zoom и Deep Zoom Composer

    На данном занятии должно быть разработано приложение Silverlight, которое предоставляет доступ к графической информации с помощью технологии Deep Zoom. Для выполнения задания необходимы средства разработки Microsoft Visual Studio 2008 и Deep Zoom Composer 3.0.

    Задание

    Создать проект в Deep Zoom Composer "автопортреты", экспортировать проект Deep Zoom в проект Silverlight и ASP.NET.

    Создание проекта Deep Zoom

    Откроем Deep Zoom Composer и создаем новый проект "автопортреты".

    (рис P.40) Создание проекта Deep Zoom

    Добавим автопортреты художников прошлого. Это картинки Леонардо да Винчи.jpg (464x650 пикселов), Лоренцо Джованни.jpg (650x831), Никола Пуссен.jpg (500x594), Рафаэль Санти.jpg (500x696) и Филиппино Липпи.jpg (460x661).

    (рис P.41) Добавление изображений в проект Deep Zoom

    После добавления увидим добавленные изображения справа. Переходим к составлению композиции по вкладке " Compose ".

    (рис P.42) Добавленные изображения в проект Deep Zoom

    На панели размещаем импортированные изображения, как позволяет фантазия дизайнера. Deep Zoom Composer позволяет масштабировать изображения как угодно. Например:

    (рис P.43) Составление композиции Deep Zoom

    Помимо простого размещения изображений на полотен, Deep Zoom Composer позволяет управлять переходами между картинками с помощью специальных элементов управления. Deep Zoom Composer позволяет делать слайдшоу, переход при нажатии на изображение как внутри композиции, так и по внешней интернет ссылке URL.

    Чтобы создать слайдшоу, необходимо открыть панель "Slideshow" и методом dragdrop перетащить изображения на панель. Создаем нужный порядок. Кнопкамиэтот порядок можно изменить.

    (рис P.44) Изготовление слайдшоу Deep Zoom

    Чтобы создать меню, необходимо открыть панель "Menu" и методом dragdrop перетащить изображение на панель меню. Название дается автоматически по имени файла, но мы можем его переименовать. Кнопкойможно автоматически создать дерево меню (default menu), согласно вложенности изображений друг в друга. Меню Deep Zoom Composerпозволяет (слева направо):

  • автоматическое создание меню по-умолчанию
  • удаление пункта меню
  • создание нового пункта меню
  • повышение уровня вложенности пункта меню
  • понижение уровня вложенности пункта меню
  • изменение порядка пункта меню вверх
  • изменение порядка пункта меню вниз
  • (рис P.45) Создание меню Deep Zoom

    Чтобы создать систему внутренних переходов, необходимо открыть панель "Internal Links", щелкнуть правой клавишей мыши по изображению, нажатие на которое приведет к переходу, "Add Internal Links".

    (рис P.46) Добавление внутренней ссылки

    И затем выбрать изображение, на которое произойдет переход.

    (рис P.47) Добавление внутренней ссылки. Выбор ссылки

    Чтобы создать систему внешних ссылок, необходимо выбрать в главном меню Deep Zoom Composer выбрать пункт "Tools/Manage External Links". И задать URL ссылки, отображаемое название и описание ссылки. Имя ссылки "Энциклопедия замечательных людей" адрес http://www.abc-people.com/data/bernini/work-1.htm.

    (рис P.48) Добавление внешней ссылки

    Затем методом dragdrop перетащить изображение "Бернини" на панель внешних ссылок. Откроется окно выбора внешних ссылок. Выбираем нужную ссылку. При нажатии на "Бернини" произойдет переход на сайт с его жизнеописанием.

    (рис P.49) Привязка внешней ссылки к изображению

    К одной ссылке можно привязать несколько изображений.

    Создание проекта Silverlight

    Для создания проекта Silverlight, который будет отображать проект Deep Zoom, необходимо экспортировать проект Deep Zoom в Visual Studio. Переходим по вкладке "Export".

    (рис P.50) Экспорт проекта Deep Zoom в проект Silverlight

    Перед экспортом можно сделать preview. Выбираем параметры экспорта тип: Silverlight Deep Zoom, экспортировать как коллекцию рисунков. Можно экспортировать в один большой рисунок. Шаблон выбираем "Blend 3 Behaviors + Source". Затем откроем папку нового проекта и откроем файл решения DeepZoomProject.sln из каталога silverlightdeepzoom. Мастер создаст следующее решение:

    (рис P.51) Экспорт Deep Zoom в проект Silverlight по шаблону "Blend 3 Behaviors + Source"

    Если запустить отладку debug, то получим следующее приложение Silverlight.

    (рис P.52) Пример работающего приложения Silverlight Deep Zoom

    Заключение

    В данной практической работе был рассмотрен пример создание приложения Silverlight Deep Zoom с помощью инструментов дизайнера Deep Zoom Composer 3.0 и программиста Visual Studio 2008. Исходный код находится в файле DeepZoom.zip.

    Создание внебраузерного приложения Silverlight

    Для выполнения данного практического задания необходимо средство разработки Visual Studio.

    Задание

    Разработать простейшее приложение Silverlight. Модифицировать его для установки на клиентском компьютере, инсталлировать и деинсталлировать приложение. Модифицировать приложение, чтобы оно могло быть обновлено, обновить приложение. Модифицировать приложение, чтобы оно могло определять наличие подключения к Интернет, проверить работу отключив сетевой интерфейс.

    Установка на клиентском компьютере

    Создаем проект Silverlight, как описано в разделе " Создание простого приложения Silverlight", согласно рис. P1, рис. P.2 и рис. P.3. Добавляем в проект файл (Add existing Item) - иконку . Открываем свойства проекта Silverlight. И включаем свойство "Enable running application out of the browser". Кроме этого задаем свойства "Out-Of-Browser Settings". Используем в качестве иконки добавленный рисунок.

    (рис P.53) Изменение свойств проекта для работы вне приложения браузера

    Добавим небольшой текст в MainPage.xaml, который будет отображать состояние приложения.

    <TextBlock 
      x:Name="textBox"
      Text="Приложение Silverlight. Версия 1" 
      HorizontalAlignment="Left"/>

    Запустим приложение и щелкнем правом клавишей мыши. Появится диалоговое окно, предлагающее установить приложение на компьютер.

    (рис P.54) Установка приложения Silverlight

    Нажимаем установить, затем выбираем места, в которые будут размещены ярлыки

    (рис P.55) Установка ярлыков

    Приложение сразу же запустится. Обратите внимание на появление ярлыков на рабочем столе и в меню программ. Теперь удалим его, щелкнув правой клавишей мыши внутри работающего приложения.

    (рис P.56) Удаление приложения

    Тоже самое можно сделать и в браузере. Приложение также будет удалено.

    Добавим в приложение код (файл MainPage.xaml.cs), позволяющий определить работает приложение в браузере или нет.

    public MainPage()
    {
        InitializeComponent();
        if (App.Current.IsRunningOutOfBrowser)
        { textBox.Text += ". Работа локально"; }
        else
        { textBox.Text += ". Работа в броузере"; }
    }

    Запускаем отладку и устанавливаем приложение локально, должно получиться:

    (рис P.57) Локальное и браузерное приложения

    Добавим кнопку, при нажатии на которую приложение будет установлено или удалено.

    <Button 
      x:Name="buttonInstall" 
      Click="Button_Click" 
      HorizontalAlignment="Left"/>

    И код в описание класса MainPage():

    if (App.Current.InstallState == 
        System.Windows.InstallState.Installed)
    {
        buttonInstall.Content = "Установлено";
    }
    else
    {
        buttonInstall.Content = " Не установлено. Установить";
    }
    App.Current.InstallStateChanged += 
        new EventHandler(Current_InstallStateChanged);

    В зависимости от состояния установки, изменяется надпись на кнопке. Кроме того, добавляется обработчик события изменения состояния установки:

    void Current_InstallStateChanged(object sender, EventArgs e)
    {
        if (App.Current.InstallState ==
            System.Windows.InstallState.Installed)
        {
            buttonInstall.Content = "Установлено";
        }
        else
        {
            buttonInstall.Content = " Не установлено. Установить";
        }
    }

    Обработчик событий нажатия кнопки:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (App.Current.InstallState ==
            System.Windows.InstallState.NotInstalled)
        {
            App.Current.Install();
        }            
    }

    После запуска должно быть:

    (рис P.58)

    При нажатии на кнопку приложение будет установлено.

    Обновление приложения

    Добавим кнопку и текст на страницу, а также, код в MainPage.xaml.cs, позволяющий отследить версию приложения и сразу же обновить его:

    <TextBlock 
      x:Name="textBox1"
      HorizontalAlignment="Left"/>
    <Button 
      x:Name="buttonUpdate"
      Content="Проверить обновления"
      Click="Button1_Click" 
      HorizontalAlignment="Left"/>
    
    private void Button1_Click(object sender, RoutedEventArgs e)
    {
        App.Current.CheckAndDownloadUpdateAsync();
        App.Current.CheckAndDownloadUpdateCompleted += 
            new CheckAndDownloadUpdateCompletedEventHandler
                (Current_CheckAndDownloadUpdateCompleted);
    }
    void Current_CheckAndDownloadUpdateCompleted
        (object sender, CheckAndDownloadUpdateCompletedEventArgs e)
    {
        if (e.UpdateAvailable)
        {
            textBox1.Text = "Установлены обновления. 
                           Перезапустите приложение";
        }
        else
        {
            textBox1.Text = "Новых обновлений нет";
        }
    }

    Запустим приложение в браузере и установим его, предварительно удалив старое. Затем изменим текст надписи в проекте на "Приложение Silverlight. Версия 2" и откомпилируем приложение 2-ой версии. Запустим приложение локально и нажмем на кнопку "Проверить обновления". Затем перезапустим его. Получим:

    (рис P.59) Проверка и установка обновлений

    При работе в браузере обновления, естественно, не проверяются, т.к. работает всегда свежая версия.

    Проверка подключения к Интернету

    Добавим в xaml файл текстовый блок:

    <TextBlock 
        x:Name="networkIndicator"
        HorizontalAlignment="Left"/>

    Он будет отражать состояние сети. В код добавим:

    using System.Net.NetworkInformation;

    и в конструктор класса MainPage():

    NetworkChange.NetworkAddressChanged += 
        new NetworkAddressChangedEventHandler
            (NetworkChange_NetworkAddressChanged);
    bool online = NetworkInterface.GetIsNetworkAvailable();
    networkIndicator.Text = online ?
        "ONLINE" : "OFFLINE";

    А также, обработчик события NetworkAddressChanged:

    void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
    {
        networkIndicator.Visibility =
            App.Current.IsRunningOutOfBrowser ?
            Visibility.Visible : Visibility.Collapsed;
        bool online = NetworkInterface.GetIsNetworkAvailable();
        networkIndicator.Text = online ?
            "ONLINE" : "OFFLINE";
    }

    Скомпилируем проект. Проверим обновления локального приложения и перезапустим его. Теперь откроем "Центр управления сетями и общим доступом" из панели управления Windows и откроем "Сетевые подключения". Теперь отключим действующее сетевое подключение:

    (рис P.60) Отключение сети

    Запустим приложение, должны увидеть следующее:

    (рис P.61) Работа локального приложения без сети

    Теперь, не закрывая, приложение включим сеть. Приложение через некоторое время определит, что сеть есть.

    (рис P.62) Работа локального приложения с сетью

    Заключение

    На данном практическом занятии мы создали Silverlight приложение, которое установили для работы локально. Рассмотрели вопросы обновления внебраузерных приложений и поддержку работы без подключения к интернету. Исходный код находится в файле

    Вернуться к учебному плану