silverlight, rich internet applications and multimedia
DESCRIPTION
24. Silverlight, Rich Internet Applications and Multimedia. Had I the heavens’ embroidered cloths, Enwrought with gold and silver light. William Butler Yeats This world is but a canvas to our imaginations. Henry David Thoreau Something deeply hidden had to be behind things. Albert Einstein. - PowerPoint PPT PresentationTRANSCRIPT
2009 Pearson Education, Inc. All rights reserved.
1
2424
Silverlight, Rich Internet Applications
and Multimedia
2009 Pearson Education, Inc. All rights reserved.
2
Had I the heavens’ embroidered cloths,Enwrought with gold and silver light.
– William Butler Yeats
This world is but a canvas toour imaginations.
– Henry David Thoreau
Something deeply hidden hadto be behind things.
– Albert Einstein
2009 Pearson Education, Inc. All rights reserved.
3
Individuality of expression is thebeginning and end of all art.
– Johann Wolfgang von Goethe
It is my intention to present—through themedium of photography—intuitive observationsof the natural world which may have meaningto the spectators.
– Ansel Adams
2009 Pearson Education, Inc. All rights reserved.
4
OBJECTIVES
In this chapter you will learn: What Silverlight is and how it relates to Windows
Presentation Foundation. To use Silverlight controls to create Rich Internet
Applications. To create custom Silverlight controls. To use animation for enhanced GUIs. To display and manipulate images. To use Silverlight with Flickr’s web services to build
an online photo-searching application. To create Silverlight deep zoom applications. To include audio and video in Silverlight applications.
2009 Pearson Education, Inc. All rights reserved.
5
24.1 Introduction
24.2 Platform Overview
24.3 Silverlight Runtime and Tools Installation
24.4 Building a Silverlight WeatherViewer Application
24.4.1 GUI Layout
24.4.2 Obtaining and Displaying Weather Forecast Data
24.4.3 Custom Controls
24.5 Animations and the FlickrViewer
24.6 Images and Deep Zoom
24.6.1 Getting Started With Deep Zoom Composer
24.6.2 Creating a Silverlight Deep Zoom Application
24.7 Audio and Video
24.8 Isolated Storage
2009 Pearson Education, Inc. All rights reserved.
6
24.1 Introduction
• SilverlightTM is Microsoft’s platform for building Rich Internet Applications (RIAs)
• RIAs are comparable in responsiveness and rich user interactivity to desktop applications.
• Silverlight is a robust, cross-platform, cross-browser subset of the .NET platform.
• Silverlight is a subset of WPF.
2009 Pearson Education, Inc. All rights reserved.
7
24.1 Introduction (Cont.)
• Silverlight supports multimedia—images, graphics, animation, sound and video.
• Most computers sold today are “multimedia ready,” with CD-RW and DVD drives, audio boards and special video capabilities.
• Computers will be needing faster processors, larger memories and wider communications bandwidths.
• WPF and Silverlight, through .NET 3.5, provide facilities for developing powerful multimedia applications.
2009 Pearson Education, Inc. All rights reserved.
8
24.2 Platform Overview
• Silverlight runs as a browser plug-in on popular browsers and operating systems.
• Silverlight applications consist of user interfaces described in XAML and code-behind files containing application logic.
• Silverlight 2 includes APIs for collections, input/output, generics, multithreading, globalization, XML and LINQ.
• It also includes APIs for interacting with JavaScript and the elements in a web page, and APIs for local storage.
• Like WPF, Silverlight provides a powerful data-binding model.
2009 Pearson Education, Inc. All rights reserved.
9
24.3 Silverlight Runtime and Tools Installation
• Install the Silverlight 2 Runtime plug-in from www.microsoft.com/silverlight/resources/installationFiles.aspx?v=2.0.
• You’ll also need the Silverlight Tools Beta 2 for Visual Studio 2008 from go.microsoft.com/fwlink/?LinkId=120319.
• Microsoft also provides the Silverlight 2 SDK Beta 2, obtainable at www.microsoft.com/downloads/ and searching for “Silverlight 2 SDK”.
2009 Pearson Education, Inc. All rights reserved.
10
24.4 Building a Silverlight WeatherViewer Application
• A basic Silverlight application has two XAML files:- Page.xaml defines the application’s GUI.
- App.xaml declares your application’s shared resources that can be applied to various GUI elements.
• Since our example applications contain only a single page, we do not use App.xaml and App.xaml.cs.
2009 Pearson Education, Inc. All rights reserved.
11
24.4 Building a Silverlight WeatherViewer Application (Cont.)
• Select File > New Project... in Visual Studio 2008.
• In the Project types window under Visual C#, select the Silverlight option. Then in the Templates window, select Silverlight Application.
• In the Add Silverlight Application dialog, select Add a new Web to the solution for hosting the control. In the Project Type drop-down menu, select Web Site.
2009 Pearson Education, Inc. All rights reserved.
12
24.4 Building a Silverlight WeatherViewer Application (Cont.)
• The Page.xaml file (Fig. 24.1) is similar to the default XAML for a WPF application.
• In Silverlight, the root element is a UserControl.
2009 Pearson Education, Inc. All rights reserved.
13
24.4 Building a Silverlight WeatherViewer Application (Cont.)
Fig. 24.1 | New Silverlight application in Visual Studio.
Silverlight project Web Application project
2009 Pearson Education, Inc. All rights reserved.
14
24.4 Building a Silverlight WeatherViewer Application (Cont.)
• A compiled Silverlight application is packaged by the IDE as a .xap file.
• The web page that hosts the Silverlight application references the Silverlight plug-in and the application’s .xap file.
• The Web Application Project is used to test the Silverlight application in a web browser.
2009 Pearson Education, Inc. All rights reserved.
15
24.4 Building a Silverlight WeatherViewer Application (Cont.)
• The first time you debug a Silverlight application, a Debugging Not Enabled dialog appears.
• Select the Modify the Web.Config file to enable debugging option.
• At the time of this writing the Design view is read-only and the Properties window is not yet enabled for Silverlight development.
• You can drag and drop Silverlight controls from the Toolbox into the XAML view.
2009 Pearson Education, Inc. All rights reserved.
16
24.4 Building a Silverlight WeatherViewer Application (Cont.)• The WeatherViewer application (Fig. 24.2) allows the
user to input a zip code and get weather information for that location.
Fig. 24.2 | WeatherViewer application displays a six-day weather forecast.The program can also display detailed information for a selected day. (Part 1 of 2.)
a)
2009 Pearson Education, Inc. All rights reserved.
17
24.4 Building a Silverlight WeatherViewer Application (Cont.)
b)
Fig. 24.2 | WeatherViewer application displays a six-day weather forecast.The program can also display detailed information for a selected day. (Part 2 of 2.)
2009 Pearson Education, Inc. All rights reserved.
18
1 <!-- Fig. 24.3: WeatherViewer.xaml -->
2 <!-- WeatherViewer displays day-by-day weather data (XAML). -->
3 <UserControl xmlns:Weather="clr-namespace:WeatherViewer"
4 x:Class="WeatherViewer.WeatherViewerPage"
5 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
6 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
7 <Grid x:Name="LayoutRoot" Background="LightSkyBlue">
8 <Grid.RowDefinitions>
9 <RowDefinition Height="35" />
10 <RowDefinition />
11 </Grid.RowDefinitions>
12
13 <Grid>
14 <Grid.ColumnDefinitions>
15 <ColumnDefinition Width="*" />
16 <ColumnDefinition Width="110" />
17 <ColumnDefinition Width="110" />
18 </Grid.ColumnDefinitions>
19
• The main layout controls of WPF are available in Silverlight.
• The XAML for the layout of the WeatherViewer application is shown in Fig. 24.3.
Outline
WeatherViewer.xaml
(1 of 4 )
Fig. 24.3 | WeatherViewer displays day-by-day weatherdata (XAML). (Part 1 of 4.)
Importing this namespace allows use of the custom WeatherDetailsView control.
This application uses a Grid layout container.
2009 Pearson Education, Inc. All rights reserved.
19
20 <!-- Border containing the title "Weather Viewer" -->
21 <Border Grid.Column="0" CornerRadius="10"
22 Background="LightGray" Margin="2">
23 <TextBlock Text="Weather Viewer" Padding="6" />
24 </Border>
25
26 <!-- zip code goes into this text box -->
27 <TextBox x:Name="inputTextBox" Grid.Column="1" FontSize="18"
28 Margin="4" TextChanged="inputTextBox_TextChanged" />
29
30 <!-- click to invoke web service -->
31 <Button x:Name="submitButton" Content="Get Weather"
32 Grid.Column="2" Margin="4" Click="submitButton_Click" />
33 </Grid>
34
35 <!-- contains weather images for several upcoming days -->
36 <ListBox x:Name="forecastList" Grid.Row="1" Margin="10"
37 SelectionChanged="forecastList_SelectionChanged">
38 <ListBox.ItemsPanel>
39 <ItemsPanelTemplate>
40 <!-- arrange items horizontally -->
41 <StackPanel Orientation="Horizontal" />
Outline
WeatherViewer.xaml
(2 of 4 )
Defining a TextBox.
Defining a Button.
Defining a horizontal StackPanel as the ListBox’s ItemsPanel.
The weather forecast is displayed inside a ListBox control.
Fig. 24.3 | WeatherViewer displays day-by-day weatherdata (XAML). (Part 2 of 4.)
Padding defines the distance between the edge of the container and embedded elements.
2009 Pearson Education, Inc. All rights reserved.
20
42 </ItemsPanelTemplate>
43 </ListBox.ItemsPanel> 44 45 <ListBox.ItemTemplate>
46 <DataTemplate>
47 <!-- represents item for a single day -->
48 <StackPanel Width="120" Orientation="Vertical"
49 HorizontalAlignment="Center">
50
51 <!-- displays image for a single day -->
52 <Image Source="{Binding WeatherImage}"
53 Margin="5" Width="55" Height="58" />
54
55 <!-- displays the day of the week -->
56 <TextBlock Text="{Binding DayOfWeek}"
57 TextAlignment="Center" FontSize="12"
58 Margin="5" TextWrapping="Wrap" />
59 </StackPanel>
60 </DataTemplate>
61 </ListBox.ItemTemplate>
62 </ListBox>
63
Outline
WeatherViewer.xaml
(3 of 4)
Binding the image to data from the web service’s XML response.
Fig. 24.3 | WeatherViewer displays day-by-day weatherdata (XAML). (Part 3 of 4.)
2009 Pearson Education, Inc. All rights reserved.
21
64 <!-- custom control for displaying detailed information -->
65 <Weather:WeatherDetailsView x:Name="completeDetails"
66 Visibility="Collapsed" Grid.RowSpan="2" />
67 </Grid>
68 </UserControl>
Outline
WeatherViewer.xaml
(4 of 4 )
Defining the WeatherDetailsView custom control element.
Fig. 24.3 | WeatherViewer displays day-by-day weatherdata (XAML). (Part 4 of 4.)
2009 Pearson Education, Inc. All rights reserved.
22
24.4 Building a Silverlight WeatherViewer Application (Cont.)
• Padding defines the distance between the edge of the container and embedded elements.
• By setting the WeatherDetailsView’s Grid.RowSpan property to 2, the control expands to hide other controls.
2009 Pearson Education, Inc. All rights reserved.
23
1 // Fig. 24.4: WeatherViewer.xaml.cs
2 // WeatherViewer displays day-by-day weather data (code-behind).
3 using System;
4 using System.Linq;
5 using System.Net;
6 using System.Windows;
7 using System.Windows.Controls;
8 using System.Windows.Input;
9 using System.Xml.Linq;
10
11 namespace WeatherViewer
12 {
13 public partial class WeatherViewerPage : UserControl
14 {
15 // object to invoke the web service
16 private WebClient weatherService = new WebClient();
17
18 // constructor
19 public WeatherViewerPage()
20 {
21 InitializeComponent();
• The WeatherViewer application’s code-behind file appears in Fig. 24.4.
Outline
WeatherViewer.xaml.cs
(1 of 6 )
Fig. 24.4 | WeatherViewer displays day-by-day weather data(code-behind). (Part 1 of 6.)
Import the System.Xml.Linq namespace, which enables LINQ to XML.
2009 Pearson Education, Inc. All rights reserved.
24
22
23 weatherService.DownloadStringCompleted +=
24 new DownloadStringCompletedEventHandler(
25 weatherService_DownloadStringCompleted );
26 } // end constructor
27
28 // when user clicks submit button, invoke web service
29 private void submitButton_Click( object sender, RoutedEventArgs e )
30 {
31 string zipcode = inputTextBox.Text; // get zipcode
32 this.Cursor = Cursors.Wait; // wait cursor
33
34 // webserviceX.net's WeatherForcast web service URL
35 string forecastURL = "http://www.webservicex.net/" +
36 "WeatherForecast.asmx/GetWeatherByZipCode?ZipCode=" +
37 zipcode;
38
39 // asynchronously invoke the web service
40 weatherService.DownloadStringAsync( new Uri( forecastURL ) );
41 } // end method submitButton_Click
42
Outline
WeatherViewer.xaml.cs
(2 of 6 )
Fig. 24.4 | WeatherViewer displays day-by-day weather data(code-behind). (Part 2 of 6.)
Get the zip code entered by the user in the TextBox
Format the web-service URL with the zip code
Call the weatherService object’s DownloadStringAsync method to invoke the web service.
2009 Pearson Education, Inc. All rights reserved.
25
43 // when download is complete for web-service result
44 private void weatherService_DownloadStringCompleted( object sender,
45 DownloadStringCompletedEventArgs e )
46 {
47 if ( e.Error == null && e.Result.Contains( "Day" ) )
48 DisplayWeatherForecast( e.Result );
49
50 this.Cursor = Cursors.Arrow; // arrow cursor
51 } // end method weatherService_DownloadStringCompleted
52
53 // display the received weather data
54 private void DisplayWeatherForecast( string xmlData )
55 {
56 // parse the XML data for use with LINQ
57 XDocument weatherXML = XDocument.Parse( xmlData );
58
59 XNamespace weatherNamespace =
60 XNamespace.Get( "http://www.webservicex.net" );
61
Outline
WeatherViewer.xaml.cs
(3 of 6 )
Fig. 24.4 | WeatherViewer displays day-by-day weather data(code-behind). (Part 3 of 6.)
The DownloadStringCompleted event handler has a parameter e of type DownloadStringCompletedEventArgs which contains information returned by the web service.
Check for an error and ensure that the result contains the desired information.
Convert the string containing the contents of the XML response to an XDocument.
Define the namespace for the XML returned by the web service and allow the application to access the data.
2009 Pearson Education, Inc. All rights reserved.
26
62 // convert XML into WeatherData objects using XML literals
63 var weatherInformation =
64 from item in weatherXML.Descendants(
65 weatherNamespace + "WeatherData" )
66 where !item.IsEmpty
67 select new WeatherData()
68 {
69 DayOfWeek = item.Element(
70 weatherNamespace + "Day" ).Value,
71 WeatherImage = item.Element(
72 weatherNamespace + "WeatherImage" ).Value,
73 HighFahrenheit = item.Element(
74 weatherNamespace + "MaxTemperatureF" ).Value,
75 LowFahrenheit = item.Element(
76 weatherNamespace + "MinTemperatureF" ).Value,
77 HighCelsius = item.Element(
78 weatherNamespace + "MaxTemperatureC" ).Value,
79 LowCelsius = item.Element(
80 weatherNamespace + "MinTemperatureC" ).Value
81 };
Outline
WeatherViewer.xaml.cs
(4 of 6 )
Fig. 24.4 | WeatherViewer displays day-by-day weather data(code-behind). (Part 4 of 6.)
The LINQ to XML query gathers the weather information and sets the corresponding values for a WeatherData object.
Class WeatherData includes all the necessary weather information for a single day of the week.
2009 Pearson Education, Inc. All rights reserved.
27
82 83 // bind forecastList.ItemSource to the weatherInformation 84 forecastList.ItemsSource = weatherInformation;
85 } // end method DisplayWeatherForecast
86
87 // displays the custom control
88 private void forecastList_SelectionChanged( object sender,
89 SelectionChangedEventArgs e )
90 {
91 // specify the WeatherData object containing the details
92 if ( forecastList.SelectedItem != null )
93 completeDetails.DataContext = forecastList.SelectedItem;
94
95 // show the complete weather details
96 completeDetails.Visibility = Visibility.Visible;
97 } // end method forecastList_SelectionChanged
98
Outline
WeatherViewer.xaml.cs
(5 of 6 )
Fig. 24.4 | WeatherViewer displays day-by-day weather data(code-behind). (Part 5 of 6.)
Bind the results of the weatherInformation LINQ query to the ListBox to display the summary of the six-day weather forecast.
When the user selects a particular day, we bind the WeatherData object for the selected day to the custom control, which displays the details for that day.
2009 Pearson Education, Inc. All rights reserved.
28
99 // remove displayed weather information when input zip code changes
100 private void inputTextBox_TextChanged( object sender,
101 TextChangedEventArgs e )
102 {
103 forecastList.ItemsSource = null;
104 } // end method inputTextBox_TextChanged
105 } // end class WeatherViewerPage
106 } // end namespace WeatherViewer
Outline
WeatherViewer.xaml.cs
(6 of 6 )
Fig. 24.4 | WeatherViewer displays day-by-day weather data(code-behind). (Part 6 of 6.)
2009 Pearson Education, Inc. All rights reserved.
29
• You must add a reference to the System.Xml.Linq assembly in addition to importing the namespace.
Error-Prevention Tip 24.1When invoking a web service that returns XML, ensure thatthe namespace you specify in your code precisely matches the namespace specified in the returned XML. Otherwise, theelements in the returned XML will not be recognized in your code.
• To add the code for a class to a project, right click the project in the Solution Explorer and select Add > Existing Item..., find the file containing the class’s code and click OK.
• In Silverlight applications, you cannot bind to anonymous types.
24.4 Building a Silverlight WeatherViewer Application (Cont.)
2009 Pearson Education, Inc. All rights reserved.
30
24.4 Building a Silverlight WeatherViewer Application (Cont.)• A sample of the web service’s XML response appears in Fig. 24.5.
Fig. 24.5 | Sample web-service XML response.
2009 Pearson Education, Inc. All rights reserved.
31
24.4 Building a Silverlight WeatherViewer Application (Cont.)
24.4.3 Custom Controls
• As with WPF, you can create custom controls using the UserControl element as a template.
• To add a new UserControl to the project, right click the project in the Solution Explorer and select Add > New Item.... Select the Silverlight User Control template and name the file (Fig. 24.6).
2009 Pearson Education, Inc. All rights reserved.
32
24.4 Building a Silverlight WeatherViewer Application (Cont.)
Fig. 24.6 | Adding a new UserControl to a Silverlight application.
• Once added to the project, a UserControl can be coded similar to any other Silverlight application.
2009 Pearson Education, Inc. All rights reserved.
33
1 <!-- Fig. 24.7: WeatherDetailsView.xaml -->
2 <!-- WeatherViewer's WeatherDetailsView custom control (XAML). -->
3 <UserControl x:Class="WeatherViewer.WeatherDetailsView"
4 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
5 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
6 <Grid>
7 <!-- background semitransparent rectangle -->
8 <Rectangle HorizontalAlignment="Stretch" Fill="Aquamarine"
9 VerticalAlignment="Stretch" Opacity="0.8" />
10
11 <!-- Border containing all the elements of the control -->
12 <Border CornerRadius="20" Background="AliceBlue"
13 BorderBrush="Blue" BorderThickness="4"
14 Width="400" Height="175">
15
• The XAML code for the WeatherDetailsView custom control’s GUI appears in Fig. 24.7.
Outline
WeatherDetailsView.xaml
(1 of 4 )
Fig. 24.7 | WeatherViewer's WeatherDetailsView customcontrol (XAML). (Part 1 of 4.)
2009 Pearson Education, Inc. All rights reserved.
34
16 <!-- StackPanel contains all the displayed weather info -->
17 <StackPanel>
18 <!-- the day and the corresponding weather image -->
19 <Image Source="{Binding WeatherImage}" Margin="5" Width="55" 20 Height="58" /> 21 <TextBlock Text="{Binding DayOfWeek}" Margin="5"
22 TextAlignment="Center" FontSize="12"
23 TextWrapping="Wrap" />
24
25 <!-- displays the temperature info in C and F -->
26 <StackPanel HorizontalAlignment="Center"
27 Orientation="Horizontal">
28 <TextBlock Text="Max F:" Margin="5" FontSize="16"/>
29 <TextBlock Text="{Binding HighFahrenheit}"
30 Margin="5" FontSize="16" FontWeight="Bold"/>
31 <TextBlock Text="Min F:" Margin="5" FontSize="16"/>
Outline
WeatherDetailsView.xaml
(2 of 4 )
Fig. 24.7 | WeatherViewer's WeatherDetailsView customcontrol (XAML). (Part 2 of 4.)
2009 Pearson Education, Inc. All rights reserved.
35
32 <TextBlock Text="{Binding LowFahrenheit}"
33 Margin="5" FontSize="16" FontWeight="Bold"/>
34 <TextBlock Text="Max C:" Margin="5" FontSize="16"/>
35 <TextBlock Text="{Binding HighCelsius}"
36 Margin="5" FontSize="16" FontWeight="Bold"/>
37 <TextBlock Text="Min C:" Margin="5" FontSize="16"/>
38 <TextBlock Text="{Binding LowCelsius}"
39 Margin="5" FontSize="16" FontWeight="Bold"/>
40 </StackPanel>
41 42 <!-- closes the control to go back to the main page --> 43 <Button x:Name="closeButton" Content="Close" Width="80"
44 Click="closeButton_Click"/>
45 </StackPanel>
46 </Border>
47 </Grid>
48 </UserControl>
Outline
WeatherDetailsView.xaml
(3 of 4 )
Fig. 24.7 | WeatherViewer's WeatherDetailsView customcontrol (XAML). (Part 3 of 4.)
2009 Pearson Education, Inc. All rights reserved.
36
Outline
WeatherDetailsView.xaml
(4 of 4 )
Fig. 24.7 | WeatherViewer's WeatherDetailsView customcontrol (XAML). (Part 4 of 4.)
2009 Pearson Education, Inc. All rights reserved.
37
1 // Fig. 24.8: WeatherDetailsView.xaml.cs
2 // WeatherViewer's WeatherDetailsView custom control (code-behind).
3 using System.Windows;
4 using System.Windows.Controls;
5
6 namespace WeatherViewer
7 {
8 public partial class WeatherDetailsView : UserControl
9 {
10 // constructor
11 public WeatherDetailsView()
12 {
13 InitializeComponent();
14 } // end constructor
15
16 // close the details view
17 private void closeButton_Click( object sender, RoutedEventArgs e )
18 {
19 this.Visibility = Visibility.Collapsed;
20 } // end method closeButton_Click
21 } // end class WeatherDetailsView
22 } // end namespace WeatherViewer
• Figure 24.8 shows the code-behind file for the WeatherDetailsView control.
Outline
WeatherDetailsView.xaml.cs
Fig. 24.8 | WeatherViewer's WeatherDetailsView customcontrol (code-behind).
The Button’s Click event handler collapses the control, so the user can continue interacting with the main page of the application.
2009 Pearson Education, Inc. All rights reserved.
38
24.5 Animations and the FlickrViewer
• Animations in Silverlight are defined in Storyboards, which are created as Resources of a control and contain one or more animation elements.
• When a Storyboard’s Begin method is called, the embedded animations begin executing.
FlickrViewer Example
• A sample screen capture of the FlickrViewer example is shown in Fig. 24.9.
2009 Pearson Education, Inc. All rights reserved.
39
24.5 Animations and the FlickrViewer (Cont.)
Fig. 24.9 | FlickrViewer allows users to search photos by tag.
2009 Pearson Education, Inc. All rights reserved.
40
24.5 Animations and the FlickrViewer (Cont.)
• A tag is any user-generated word or phrase that helps organize web content.
• Flickr uses tags on uploaded files to improve its photo-search service, giving the user better results.
2009 Pearson Education, Inc. All rights reserved.
41
24.5 Animations and the FlickrViewer (Cont.)
• You can type one or more tags into the application’s TextBox and click the Search Button to invoke the Flickr web service
• The web service responds with an XML document containing links to the photos that match the tags.
• The application parses the XML and displays thumbnails of the photos.
2009 Pearson Education, Inc. All rights reserved.
42
1 <!-- Fig. 24.10: FlickrViewer.xaml -->
2 <!-- FlickrViewer allows users to search for tagged photos (XAML). -->
3 <UserControl x:Class="FlickrViewer.FlickrViewerPage"
4 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
5 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
6 <Grid x:Name="LayoutRoot">
7 <Grid.RowDefinitions>
8 <RowDefinition Height="Auto" />
9 <RowDefinition x:Name="imageRow" />
10 <RowDefinition Height="Auto" />
11 </Grid.RowDefinitions>
12
13 <Grid.Resources>
14 <!-- enlarge the Border to display a new image -->
15 <Storyboard x:Name="animateIn" Completed="animateIn_Completed"
16 Storyboard.TargetName="largeCoverImage">
17 <DoubleAnimation x:Name="animate"
18 Storyboard.TargetProperty="Height" Duration="0:0:0.45" />
19 </Storyboard>
20
• The application’s XAML is shown in Fig. 24.10.Outline
FlickrViewer.xaml
(1 of 4 )
Fig. 24.10 | FlickrViewer allows users to search for taggedphotos (XAML). (Part 1 of 4.)
The animateIn Storyboard contains a DoubleAnimation that animates the Height property of the largeCoverImage’s Border.
2009 Pearson Education, Inc. All rights reserved.
43
21 <!-- collapse the Border in preparation for a new image -->
22 <Storyboard x:Name="animateOut" Completed="animateOut_Completed"
23 Storyboard.TargetName="largeCoverImage">
24 <DoubleAnimation Storyboard.TargetProperty="Height" To="60"
25 Duration="0:0:0.25" />
26 </Storyboard>
27 </Grid.Resources>
28
29 <!-- the search box and button for user interaction -->
30 <StackPanel Grid.Row="0" Orientation="Horizontal">
31 <TextBox x:Name="searchBox" Width="150" />
32 <Button x:Name="searchButton" Content="Search" Width="75"
33 Click="searchButton_Click" />
34 </StackPanel>
35
36 <!-- Border that contains the large main image -->
37 <Border Grid.Row="1" x:Name="largeCoverImage" Height="60"
38 BorderBrush="Black" BorderThickness="10" CornerRadius="10"
39 Padding="20" Margin="10" HorizontalAlignment="Center">
40 <Border.Background>
41 <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
Outline
FlickrViewer.xaml
(2 of 4 )
Fig. 24.10 | FlickrViewer allows users to search for taggedphotos (XAML). (Part 2 of 4.)
The animateOut Storyboard shrinks the Border until the image inside is no longer visible.
2009 Pearson Education, Inc. All rights reserved.
44
42 <GradientStop Offset="0" Color="Black" />
43 <GradientStop Offset="1" Color="LightGray" />
44 </LinearGradientBrush>
45 </Border.Background> 46 47 <!-- display the image that the user selected -->
48 <Image Source="{Binding}" Stretch="Uniform" />
49 </Border>
50
51 <!-- Listbox displays thumbnails of the search results -->
52 <ListBox x:Name="thumbsListBox" HorizontalAlignment="Center"
53 SelectionChanged="thumbsListBox_SelectionChanged" Grid.Row="2">
54 <ListBox.ItemsPanel>
55 <ItemsPanelTemplate>
56 <StackPanel Orientation="Horizontal"/>
57 </ItemsPanelTemplate>
58 </ListBox.ItemsPanel>
59
60 <ListBox.ItemTemplate>
61 <DataTemplate>
62 <Image Source="{Binding}" Margin="10" />
Outline
FlickrViewer.xaml
(3 of 4 )
Fig. 24.10 | FlickrViewer allows users to search for taggedphotos (XAML). (Part 3 of 4.)
2009 Pearson Education, Inc. All rights reserved.
45
63 </DataTemplate>
64 </ListBox.ItemTemplate>
65 </ListBox>
66 </Grid>
67 </UserControl>
Outline
FlickrViewer.xaml
(4 of 4 )
Fig. 24.10 | FlickrViewer allows users to search for taggedphotos (XAML). (Part 4 of 4.)
2009 Pearson Education, Inc. All rights reserved.
46
1 // Fig. 24.11: FlickrViewer.xaml.cs
2 // FlickrViewer allows users to search for photos (code-behind).
3 using System;
4 using System.Linq;
5 using System.Net;
6 using System.Windows;
7 using System.Windows.Controls;
8 using System.Xml.Linq;
9
10 namespace FlickrViewer
11 {
12 public partial class FlickrViewerPage : UserControl
13 {
14 // Flickr API key
15 private const string KEY = "Your API key goes here as string";
16
17 // object used to invoke Flickr web service
18 private WebClient flickr = new WebClient();
19
• The code-behind for FlickrViewer application can be seen in Fig. 24.11.
Outline
FlickrViewer.xaml.cs
(1 of 6 )
Fig. 24.11 | FlickrViewer allows users to search for photos(code-behind). (Part 1 of 6.)
To run this application you need to insert your Flickr API key here.
2009 Pearson Education, Inc. All rights reserved.
47
20 // constructor
21 public FlickrViewerPage()
22 {
23 InitializeComponent();
24 flickr.DownloadStringCompleted += new
25 DownloadStringCompletedEventHandler(
26 flickr_DownloadStringCompleted );
27 } // end constructor
28
29 // when the photo selection has changed
30 private void thumbsListBox_SelectionChanged( object sender,
31 SelectionChangedEventArgs e )
32 {
33 // set the height back to a value so that it can be animated
34 largeCoverImage.Height = largeCoverImage.ActualHeight;
35
36 animateOut.Begin(); // begin shrinking animation
37 } // end method thumbsListBox_SelectionChanged
38
Outline
FlickrViewer.xaml.cs
(2 of 6 )
Fig. 24.11 | FlickrViewer allows users to search for photos(code-behind). (Part 2 of 6.)
Assign the value largeImageCover.ActualHeight to the Border’s Height so it can be animated.
2009 Pearson Education, Inc. All rights reserved.
48
39 // once the nested image is no longer visible
40 private void animateOut_Completed( object sender, EventArgs e )
41 {
42 if ( thumbsListBox.SelectedItem != null )
43 {
44 // grab the URL of the selected item's full image
45 string photoURL =
46 thumbsListBox.SelectedItem.ToString().Replace(
47 "_t.jpg", ".jpg" );
48
49 largeCoverImage.DataContext = photoURL;
50
51 animate.To = imageRow.ActualHeight - 20;
52 animateIn.Begin();
53 } // end if
54 } // end method animateOut_Completed
55
56 // this makes sure that the border will resize with the window
57 private void animateIn_Completed( object sender, EventArgs e )
Outline
FlickrViewer.xaml.cs
(3 of 6 )
Fig. 24.11 | FlickrViewer allows users to search for photos(code-behind). (Part 3 of 6.)
To load the large Image, use the URL of the thumbnail and remove the “_t” from the link.
set the To property to the Height of the page’s second row (minus 20 to account for the Border’s Margin).
2009 Pearson Education, Inc. All rights reserved.
49
58 {
59 largeCoverImage.Height = double.NaN; // image height = *
60 } // end method animateIn_Completed
61
62 // begin the search when the user clicks the search button
63 private void searchButton_Click( object sender, RoutedEventArgs e )
64 {
65 // Flickr's web-service URL for searches
66 var flickrURL = string.Format("http://api.flickr.com/services" +
67 "/rest/?method=flickr.photos.search&api_key={0}&tags={1}" +
68 "&tag_mode=all&per_page=20&privacy_filter=1", KEY,
69 searchBox.Text.Replace( " " , "," ) );
70
71 // invoke the web service
72 flickr.DownloadStringAsync( new Uri( flickrURL ) );
73
74 // disable the search button
75 searchButton.Content = "Loading...";
76 searchButton.IsEnabled = false;
77 } // end method searchButton_Click
Outline
FlickrViewer.xaml.cs
(4 of 6 )
Fig. 24.11 | FlickrViewer allows users to search for photos(code-behind). (Part 4 of 6.)
Reset the Border’s Height back to double.NaN, which allows the border to be resized with the window.
2009 Pearson Education, Inc. All rights reserved.
50
78
79 // once we have received the XML file from Flickr
80 private void flickr_DownloadStringCompleted( object sender,
81 DownloadStringCompletedEventArgs e )
82 {
83 searchButton.Content = "Search";
84 searchButton.IsEnabled = true;
85
86 if ( e.Error == null )
87 {
88 // parse the data with LINQ
89 XDocument flickrXML = XDocument.Parse( e.Result );
90
91 // gather information on all photos
92 var flickrPhotos =
93 from photo in flickrXML.Descendants( "photo" )
94 let id = photo.Attribute( "id" ).Value
95 let secret = photo.Attribute( "secret" ).Value
96 let server = photo.Attribute( "server" ).Value
Outline
FlickrViewer.xaml.cs
(5 of 6 )
Fig. 24.11 | FlickrViewer allows users to search for photos(code-behind). (Part 5 of 6.)
Use a LINQ query to gather the necessary information from the attributes of the photo elements in the XML returned by the web service.
2009 Pearson Education, Inc. All rights reserved.
51
97 let farm = photo.Attribute( "farm" ).Value
98 select string.Format(
99 "http://farm{0}.static.flickr.com/{1}/{2}_{3}_t.jpg",
100 farm, server, id, secret);
101
102 // set thumbsListBox's item source to the URLs we received
103 thumbsListBox.ItemsSource = flickrPhotos;
104 } // end if
105 } // end method flickr_DownloadStringCompleted
106 } // end class FlickrViewerPage
107 } // end namespace FlickrViewer
Outline
FlickrViewer.xaml.cs
(6 of 6 )
Fig. 24.11 | FlickrViewer allows users to search for photos(code-behind). (Part 6 of 6.)
Use a LINQ query to gather the necessary information from the attributes of the photo elements in the XML returned by the web service.
2009 Pearson Education, Inc. All rights reserved.
52
1 <?xml version="1.0" encoding="utf-8" ?>
2 <rsp stat="ok">
3 <photos page="1" pages="1" perpage="20" total="5">
4 <photo id="2608518732" owner="8832668@N04" secret="76dab8eb42"
5 server="3185" farm="4" title="Red Flowers 1" ispublic="1"
6 isfriend="0" isfamily="0" />
7 <photo id="2608518654" owner="8832668@N04" secret="57d35c8f64"
8 server="3293" farm="4" title="Lavender Flowers" ispublic="1"
9 isfriend="0" isfamily="0" />
10 <photo id="2608518890" owner="8832668@N04" secret="98fcb5fb42"
11 server="3121" farm="4" title="Yellow Flowers" ispublic="1"
12 isfriend="0" isfamily="0" />
13 <photo id="2608518370" owner="8832668@N04" secret="0099e12778"
14 server="3076" farm="4" title="Fuscia Flowers" ispublic="1"
15 isfriend="0" isfamily="0" />
16 <photo id="2607687273" owner="8832668@N04" secret="4b630e31ba"
17 server="3283" farm="4" title="Red Flowers 2" ispublic="1"
18 isfriend="0" isfamily="0" />
19 </photos>
20 </rsp>
• For animations to function properly, the properties being animated must contain numeric values—relative values "*" and "Auto" do not work.
• A sample of the XML response is shown in Fig. 24.12.
Outline
Fig. 24.12 | Sample XML response from the Flickr APIs.
Values used to form the URL to the online photos.
2009 Pearson Education, Inc. All rights reserved.
53
24.6 Images and Deep Zoom
• Silverlight’s deep zoom capabilities use Multi Scale Images to allow you to zoom far into an image in a web browser while maintaining quality.
• Deep zoom works by sending only the necessary image data for the part of the image you are viewing to your machine.
• To split an image or collage of images into the Silverlight-ready format used by MultiScaleImages, you use the Deep Zoom Composer.
• A MultiScaleImage’s Source is an XML document created by Deep Zoom Composer.
• A MultiScaleSubImage of a MultiScaleImage contains information on a single image in a collage.
2009 Pearson Education, Inc. All rights reserved.
54
24.6 Images and Deep Zoom (Cont.)
The DeepZoomCoverCollage Example
• Figure 24.13 shows screen captures of the application.
– Figure 24.13(a) shows the application when it’s first loaded with all 11 cover images displayed.
– Figure 24.13(b) shows the application after we’ve zoomed in closely on the leftmost small cover image.
– Figure 24.13(c) shows the application with an even deeper zoom on a different cover.
2009 Pearson Education, Inc. All rights reserved.
55
24.6 Images and Deep Zoom (Cont.)
Fig. 24.13 | Main page of the DeepZoomCoverCollage. (Part 1 of 3.)
a) The full deep zoom collage.
Small images
nested among
larger images
in the collage
2009 Pearson Education, Inc. All rights reserved.
56
24.6 Images and Deep Zoom (Cont.)
Fig. 24.13 | Main page of the DeepZoomCoverCollage. (Part 2 of 3.)
b) Zoomed in on a small cover in the middle of the collage
2009 Pearson Education, Inc. All rights reserved.
57
24.6 Images and Deep Zoom (Cont.)
Fig. 24.13 | Main page of the DeepZoomCoverCollage. (Part 3 of 3.)
c) Deep zoom showing the details of the Visual C++ How to Program cover.
2009 Pearson Education, Inc. All rights reserved.
58
24.6 Images and Deep Zoom (Cont.)
24.6.1 Getting Started With Deep Zoom Composer• Create a new project through the File menu, and specify the
project’s Name and Location.
• Figure 24.14 shows the New Project dialog.
Fig. 24.14 | Deep Zoom Composer’s New Project dialog.
2009 Pearson Education, Inc. All rights reserved.
59
24.6 Images and Deep Zoom (Cont.)
• Click the Add Image… button to add your images.
• Deep Zoom Composer supports .jpg, .tif, .bmp and .png formats.
• Figure 24.15 shows the window with the Import tab open after the book-cover images have been imported to the project.
2009 Pearson Education, Inc. All rights reserved.
60
24.6 Images and Deep Zoom (Cont.)
Fig. 24.15 | Deep Zoom Composer showing the imported image files.
2009 Pearson Education, Inc. All rights reserved.
61
24.6 Images and Deep Zoom (Cont.)
• Use the Compose tab to organize the images on your collage.
• Figure 24.16 shows what the composer looks like once you bring files into the project.
2009 Pearson Education, Inc. All rights reserved.
62
24.6 Images and Deep Zoom (Cont.)
Fig. 24.16 | Deep Zoom Composer showing the editable composition. (Part 1 of 2.)
a) Deep Zoom Composer showing the entire composition.
2009 Pearson Education, Inc. All rights reserved.
63
24.6 Images and Deep Zoom (Cont.)
Fig. 24.16 | Deep Zoom Composer showing the editable composition. (Part 2 of 2.)
b) Zoomed in on the composition in Deep Zoom Composer
2009 Pearson Education, Inc. All rights reserved.
64
24.6 Images and Deep Zoom (Cont.)
• When images are in the composition, you can move and resize them.
• The Layer View view is used to control the order of overlapping images.
• Use the Export tab to export the files to be used by a MultiScaleImage in your application.
• Figure 24.17 shows the contents of the window under the Export tab.
2009 Pearson Education, Inc. All rights reserved.
65
24.6 Images and Deep Zoom (Cont.)
Fig. 24.17 | Deep Zoom Composer’s exporting capabilities
2009 Pearson Education, Inc. All rights reserved.
66
24.6 Images and Deep Zoom (Cont.)
• The files are exported to a new folder inside the directory thatyou created earlier for the Deep Zoom Composer project.
• By default, Deep Zoom Composer selects the Export as Collection option using a PNG file format.
• By exporting as a collection instead of a composition, subimage information is included in the output XML files.
• Change the file format to JPEG and keep the Quality at 95—lower values result in smaller file sizes and lower-quality images.
• Select the Export Images option, since we are using the export in our own Silverlight project. Note that Deep Zoom
2009 Pearson Education, Inc. All rights reserved.
67
1 <!-- Fig. 24.18: DeepZoomCoverCollage.xaml -->
2 <!-- DeepZoomCoverCollage employs Silverlight's deep zoom (XAML). -->
3 <UserControl x:Class="DeepZoomCoverCollage.DeepZoomCoverCollagePage"
4 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
5 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
6 x:Name="mainPage" KeyDown="mainPage_KeyDown" KeyUp="mainPage_KeyUp">
7 <Grid x:Name="LayoutRoot">
8
9 <!-- instructions on how to interact with the page -->
10 <StackPanel Orientation="Vertical">
11 <TextBlock Text="Hold the I-key and click to zoom in." />
12 <TextBlock Text="Hold the O-key and click to zoom out." />
13 <TextBlock Text="Drag to pan the image." />
• Deep zoom images are created in Silverlight projects by using the MultiScaleImage element, which takes an XML file as its source.
• Figure 24.18 shows the XAML code that produces the layout of this application.
Outline
DeepZoomCoverCollage.xaml
(1 of 2 )
Fig. 24.18 | DeepZoomCoverCollage employs Silverlight'sdeep zoom (XAML). (Part 1 of 2.)
2009 Pearson Education, Inc. All rights reserved.
68
14
15 <TextBlock x:Name="titleTextBlock" Text="Title:"
16 HorizontalAlignment="Center" />
17
18 <!-- deep zoom collage that was created in Composer -->
19 <MultiScaleImage x:Name="Image" Margin="10"
20 Source="/CoverCollageCollection/dzc_output.xml"
21 MouseLeave="Image_MouseLeave" MouseMove="Image_MouseMove"
22 MouseLeftButtonDown="Image_MouseLeftButtonDown"
23 MouseLeftButtonUp="Image_MouseLeftButtonUp" />
24 </StackPanel>
25 </Grid>
26 </UserControl>
Outline
DeepZoomCoverCollage.xaml
(2 of 2 )
Fig. 24.18 | DeepZoomCoverCollage employs Silverlight'sdeep zoom (XAML). (Part 2 of 2.)
Set the source of the MultiScaleImage.
2009 Pearson Education, Inc. All rights reserved.
69
24.6 Images and Deep Zoom (Cont.)
• Add the entire CoverCollageCollection folder to your web application project.
– Copy the CoverCollageCollection folder into the ClientBin folder of the web application in Windows Explorer.
– Right click ClientBin under the DeepZoomCoverCollageWeb project in the Solution Explorer in Visual Studio and click Refresh Folder.
• You should see a CoverCollageCollection folder (Fig. 24.19).
2009 Pearson Education, Inc. All rights reserved.
70
24.6 Images and Deep Zoom (Cont.)
Fig. 24.19 | Solution Explorer after the deep zoom files have beenadded to the project.
2009 Pearson Education, Inc. All rights reserved.
71
1 // Fig. 24.20: DeepZoomCoverCollage.xaml.cs
2 // DeepZoomCoverCollage employs Silverlight's deep zoom (code-behind).
3 using System;
4 using System.IO;
5 using System.Linq;
6 using System.Windows;
7 using System.Windows.Controls;
8 using System.Windows.Input;
9 using System.Xml.Linq;
10
11 namespace DeepZoomCoverCollage
12 {
13 public partial class DeepZoomCoverCollagePage : UserControl
14 {
15 private const double ZOOMFACTOR = 2.0;
16
17 private bool zoomIn = false; // true if I button is pressed
18 private bool zoomOut = false; // true if O button is pressed
19 private bool mouseDown = false; // true if mouse button is down
• The application’s event handlers for zooming and panning the image, and for displaying a book’s title when its cover is clicked are shown in Fig. 24.20.
Outline
DeepZoomCoverCollage.xaml.cs
(1 of 9 )
Fig. 24.20 | DeepZoomCoverCollage employs Silverlight'sdeep zoom (code-behind). (Part 1 of 9.)
2009 Pearson Education, Inc. All rights reserved.
72
20 private Point currentPosition; // position of viewport when clicked
21 private Point dragOffset; // mouse offset used for panning
22
23 // constructor
24 public DeepZoomCoverCollagePage()
25 {
26 InitializeComponent();
27 } // end constructor
28
29 // when a key is pressed, set the correct variables to true
30 private void mainPage_KeyDown( object sender, KeyEventArgs e )
31 {
32 if ( e.Key == Key.I ) // button pressed is I
33 {
34 zoomIn = true; // prepare to zoom in
35 } // end if
36 else if ( e.Key == Key.O ) // button pressed is O
37 {
38 zoomOut = true; // prepare to zoom out
39 } // end else if
40 } // end method mainPage_KeyDown
Outline
DeepZoomCoverCollage.xaml.cs
(2 of 9 )
Fig. 24.20 | DeepZoomCoverCollage employs Silverlight'sdeep zoom (code-behind). (Part 2 of 9.)
2009 Pearson Education, Inc. All rights reserved.
73
41
42 // when a key is released, set the correct variables to false
43 private void mainPage_KeyUp( object sender, KeyEventArgs e )
44 {
45 if ( e.Key == Key.I ) // button released is I
46 {
47 zoomIn = false; // don't zoom in
48 } // end if
49 else if ( e.Key == Key.O ) // button released is O
50 {
51 zoomOut = false; // don't zoom out
52 } // end else if
53 } // end method mainPage_KeyUp
54
55 // when the mouse leaves the area of the image we don't want to pan
56 private void Image_MouseLeave( object sender, MouseEventArgs e )
57 {
58 mouseDown = false; // if mouse leaves area, no more panning
59 } // end method Image_MouseLeave
60
Outline
DeepZoomCoverCollage.xaml.cs
(3 of 9 )
Fig. 24.20 | DeepZoomCoverCollage employs Silverlight'sdeep zoom (code-behind). (Part 3 of 9.)
2009 Pearson Education, Inc. All rights reserved.
74
61 // handle events when user clicks the mouse
62 private void Image_MouseLeftButtonDown( object sender,
63 MouseButtonEventArgs e )
64 {
65 mouseDown = true; // mouse button is down
66 currentPosition = Image.ViewportOrigin; // viewport position
67 dragOffset = e.GetPosition( Image ); // mouse position
68
69 // logical position (between 0 and 1) of mouse
70 Point click = Image.ElementToLogicalPoint( dragOffset );
71
72 if ( zoomIn ) // zoom in when I key is pressed
73 {
74 Image.ZoomAboutLogicalPoint( ZOOMFACTOR, click.X, click.Y );
75 } // end if
76 else if ( zoomOut ) // zoom out when O key is pressed
77 {
78 Image.ZoomAboutLogicalPoint( 1 / ZOOMFACTOR,
79 click.X, click.Y );
80 } // end else if
Outline
DeepZoomCoverCollage.xaml.cs
(4 of 9 )
Fig. 24.20 | DeepZoomCoverCollage employs Silverlight'sdeep zoom (code-behind). (Part 4 of 9.)
MultiScaleImage’s ElementToLogicalPoint method converts the absolute coordinates raised by a mouse event to the logical coordinates required by ZoomAboutLogicalPoint.
A MultiScaleImage’s ZoomAboutLogicalPoint method zooms toward or away from the coordinates passed to the method, using the zoom factor to determine the scale of the zoom.
2009 Pearson Education, Inc. All rights reserved.
75
81
82 // determine which book cover was pressed to display the title
83 int index = SubImageIndex( click );
84
85 if ( index > -1 )
86 {
87 titleTextBlock.Text = string.Format(
88 "Title: {0}", GetTitle( index ) );
89 }
90 else // user clicked a blank space
91 {
92 titleTextBlock.Text = "Title:";
93 } // end else
94 } // end method Image_MouseLeftButtonDown
95
96 // if the mouse button is released, we don't want to pan anymore
97 private void Image_MouseLeftButtonUp( object sender,
98 MouseButtonEventArgs e )
99 {
100 mouseDown = false; // no more panning
101 } // end method Image_MouseLeftButtonUp
Outline
DeepZoomCoverCollage.xaml.cs
(5 of 9 )
Fig. 24.20 | DeepZoomCoverCollage employs Silverlight'sdeep zoom (code-behind). (Part 5 of 9.)
2009 Pearson Education, Inc. All rights reserved.
76
102
103 // handle when the mouse moves: panning
104 private void Image_MouseMove( object sender, MouseEventArgs e )
105 {
106 // if no zoom occurs, we want to pan
107 if ( mouseDown && !zoomIn && !zoomOut )
108 {
109 Point click = new Point(); // records point to move to
110 click.X = currentPosition.X - Image.ViewportWidth * (
111 e.GetPosition( Image ).X - dragOffset.X ) /
112 Image.ActualWidth;
113 click.Y = currentPosition.Y - Image.ViewportWidth * (
114 e.GetPosition( Image ).Y - dragOffset.Y ) /
115 Image.ActualWidth;
116 Image.ViewportOrigin = click; // pans the image
117 } // end if
118 } // end method Image_MouseMove
119
Outline
DeepZoomCoverCollage.xaml.cs
(6 of 9 )
Fig. 24.20 | DeepZoomCoverCollage employs Silverlight'sdeep zoom (code-behind). (Part 6 of 9.)
To pan, change the ViewportOrigin property of the MultiScaleImage, which returns a point representing the top-left corner of the viewport with respect to the collage’s top-left corner.
2009 Pearson Education, Inc. All rights reserved.
77
120 // returns the index of the clicked subimage
121 private int SubImageIndex( Point click )
122 {
123 // go through images such that images on top are processed first
124 for ( int i = Image.SubImages.Count - 1; i >= 0; i-- )
125 {
126 // select a single subimage
127 MultiScaleSubImage subImage = Image.SubImages[ i ];
128
129 // create a rect around the area of the cover
130 double scale = 1 / subImage.ViewportWidth;
131 Rect area = new Rect( -subImage.ViewportOrigin.X * scale,
132 -subImage.ViewportOrigin.Y * scale, scale, scale /
133 subImage.AspectRatio );
134
135 if ( area.Contains( click ) )
137 return i; // return the index of the clicked cover
138 } // end if
139 } // end for
140 return -1; // if no cover was clicked, return -1
141 } // end method SubImageIndex
Outline
DeepZoomCoverCollage.xaml.cs
(7 of 9 )
Fig. 24.20 | DeepZoomCoverCollage employs Silverlight'sdeep zoom (code-behind). (Part 7 of 9.)
To determine which cover the user clicked, create a Rect object for each subimage that represents the on-screen area that the image occupies.
We use Rect method Contains to determine whether the click was inside the rectangle.
2009 Pearson Education, Inc. All rights reserved.
78
142
143 // returns the title of the subimage with the given index
144 private string GetTitle( int index )
145 {
146 // XDocument that contains info on all subimages in the collage
147 XDocument xmlDocument = XDocument.Load( "Metadata.xml" );
148
149 // LINQ to XML to find the title based on index of clicked image
150 var bookTitle =
151 from info in xmlDocument.Descendants( "Image" )
152 let order = Convert.ToInt32( info.Element( "ZOrder" ).Value )
153 where order == index + 1
154 select info.Element( "FileName" ).Value;
155
156 string title = bookTitle.Single(); // gets book title
157
158 // only want title of book, not the rest of the file name
Outline
DeepZoomCoverCollage.xaml.cs
(8 of 9 )
Fig. 24.20 | DeepZoomCoverCollage employs Silverlight'sdeep zoom (code-behind). (Part 8 of 9.)
Use the subimage’s index in a LINQ to XML query to locate the subimage’s information in the Metadata.xml document.
Use use the Single method on our LINQ query result to get the one (and only) returned string.
2009 Pearson Education, Inc. All rights reserved.
79
159 title = Path.GetFileName( title ); 160 161 // make slight changes to the file name
162 title = title.Replace( ".jpg", string.Empty );
163 title = title.Replace( "pp", "++" );
164 title = title.Replace( "sharp", "#" );
165
166 // display the title on the page
167 return title.ToUpper();
168 } // end method GetTitle
169 } // end class DeepZoomCoverCollagePage
170 } // end namespace DeepZoomCoverCollage
Outline
DeepZoomCoverCollage.xaml.cs
(9 of 9 )
Fig. 24.20 | DeepZoomCoverCollage employs Silverlight'sdeep zoom (code-behind). (Part 9 of 9.)
Obtain the title from the subimage’s original file name and display the title above the deep zoom image.
2009 Pearson Education, Inc. All rights reserved.
80
24.6 Images and Deep Zoom (Cont.)
• A MultiScaleImage’sZoomAboutLogicalPoint method zooms toward or away from the coordinates passed to the method, using the zoom factor to determine the scale of the zoom.
• MultiScaleImage’s ElementToLogicalPoint method converts the absolute coordinates raised by a mouse event to the logical coordinates required by ZoomAboutLogicalPoint.
• The viewport of a MultiScaleImage represents the portionof the image that is rendered on screen.
• To pan, change the ViewportOrigin property of the MultiScaleImage, which returns a point representing thetop-left corner of the viewport with respect to the collage’stop-left corner.
2009 Pearson Education, Inc. All rights reserved.
81
24.6 Images and Deep Zoom (Cont.)
• Figures 24.21–24.22 demonstrate what values are returned by various MultiScaleImage properties.
– Assume the “container” of Fig. 24.21 is the viewport while the “image” is the entire collage.
Fig. 24.21 | Various values used to by MultiScaleImage’s properties.
2009 Pearson Education, Inc. All rights reserved.
82
Property Value
ViewportOrigin
ViewportWidth
AspectRatio
ActualWidth
x y,
imageWidth imageWidth
containerWidth
imageWidth
imageHeight
containerWidth
imageWidth
Fig. 24.22 | Ratios returned by MultiScaleImage’s properties.
24.6 Images and Deep Zoom (Cont.)
2009 Pearson Education, Inc. All rights reserved.
83
24.6 Images and Deep Zoom (Cont.)
• Determining a clicked image’s book title requires the Metadata.xml file created by Deep Zoom Composer.
• In the Solution Explorer, find this XML file in the collection folder you imported and drag the file to your Silverlight deep zoom project.
• The file contains information on where each subimage is located in the collage.
• To determine which cover the user clicked, create a Rect object for each subimage that represents the on-screen area that the image occupies.
• We use Rect method Contains to determine whether the click was inside the rectangle.
2009 Pearson Education, Inc. All rights reserved.
84
24.6 Images and Deep Zoom (Cont.)
• A MultiScaleSubImage’s properties return the same ratios as a MultiScaleImage’s properties, except that the “container” represents the entire collage while the “image” represents the subimage.
• Use the subimage’s index in a LINQ to XML query to locate the subimage’s information in the Metadata.xml document.
• Obtain the title from the subimage’s original file name and display the title above the deep zoom image.
• Use use the Single method on our LINQ query result to get the one (and only) returned string.
2009 Pearson Education, Inc. All rights reserved.
85
24.7 Audio and Video
• Silverlight uses the MediaElement element to embed audio or video files into your application.
• The source for MediaElements can be either a file stored with the Silverlight application or a source on the Internet.
• MediaElement supports playback in the following encoded formats
– Video: WMV1, WMV2, WMV3, WMVA, WMVC1
– Audio: WMA7, WMA8, WMA9, MP3
• Microsoft’s Expression Encoder can be used to convert files into a supported format.
2009 Pearson Education, Inc. All rights reserved.
86
24.7 Audio and Video (Cont.)
• MediaElements can be in one of the following states—Buffering, Closed, Paused, Opening, Playing or Stopped.
• A MediaElement’s state can be determined from its CurrentState property.
– When in the Buffering state, the MediaElement is loading the media in preparation for playback.
– When in the Closedstate, the MediaElement contains no media and displays a transparent frame.
– When in theOpening state, the MediaElement is attempting to load the media from the given source.
2009 Pearson Education, Inc. All rights reserved.
87
1 <!-- Fig. 24.23: VideoSelector.xaml -->
2 <!-- VideoSelector lets users watch several videos at once (XAML). -->
3 <UserControl x:Class="VideoSelector.VideoSelectorPage"
4 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
5 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
6 <Grid x:Name="LayoutRoot">
7 <Grid.ColumnDefinitions>
8 <ColumnDefinition Width="Auto" />
9 <ColumnDefinition />
10 </Grid.ColumnDefinitions>
11
12 <Grid.Resources>
13 <!-- Fades the main screen in, displaying the new video -->
14 <Storyboard x:Name="fadeIn" Storyboard.TargetName="screen">
15 <DoubleAnimation Storyboard.TargetProperty="Opacity"
16 From="0" To="1" Duration="0:0:0.5" />
17 </Storyboard>
18
19 <!-- Fades the main screen out when a new video is selected -->
20 <Storyboard x:Name="fadeOut" Storyboard.TargetName="screen"
• Our VideoSelector application (Fig. 24.23) shows some of Silverlight’s media-playing capabilities.
Outline
VideoSelector.xaml
(1 of 3 )
Fig. 24.23 | VideoSelector lets users watch several videosat once (XAML). (Part 1 of 3.)
DoubleAnimation that targets the Opacity property of the Rectangle that displays the video.
2009 Pearson Education, Inc. All rights reserved.
88
21 Completed="fadeOut_Completed">
22 <DoubleAnimation Storyboard.TargetProperty="Opacity"
23 From="1" To="0" Duration="0:0:0.5" />
24 </Storyboard>
25 </Grid.Resources>
26
27 <!-- ListBox containing all available videos -->
28 <ListBox x:Name="previewListBox"
29 SelectionChanged="previewListBox_SelectionChanged">
30 <ListBox.ItemsPanel>
31 <ItemsPanelTemplate>
32 <StackPanel Orientation="Vertical" />
33 </ItemsPanelTemplate>
34 </ListBox.ItemsPanel>
35 </ListBox>
36
37 <!-- Rectangle object with a video brush showing the main video -->
38 <Rectangle x:Name="screen" Grid.Column="1">
39 <Rectangle.Fill>
40 <VideoBrush x:Name="brush" Stretch="Uniform" />
41 </Rectangle.Fill>
42 </Rectangle>
43 </Grid>
44 </UserControl>
Outline
VideoSelector.xaml
(2 of 3 )
Fig. 24.23 | VideoSelector lets users watch several videosat once (XAML). (Part 2 of 3.)
A VideoBrush displays a video as a graphics object’s Fill—similar to an ImageBrush.
2009 Pearson Education, Inc. All rights reserved.
89
Outline
VideoSelector.xaml
(3 of 3 )
Fig. 24.23 | VideoSelector lets users watch several videosat once (XAML). (Part 3 of 3.)
2009 Pearson Education, Inc. All rights reserved.
90
1 <?xml version="1.0" encoding="utf-8" ?>
2
3 <!-- Fig. 24.24: sources.xml -->
4 <!-- VideoSelector's list of video sources. -->
5 <videos>
6 <video> <!-- each video child contains a uri source property -->
7 <uri>/newfractal.wmv</uri> <!-- source for first video -->
8 </video>
9 <video>
10 <uri>/fractal.wmv</uri> <!-- source for second video -->
11 </video>
12 <video>
13 <uri>/bailey.wmv</uri> <!-- source for third video -->
14 </video>
15 </videos>
• When the page loads, it first loads a new MediaElement for each source that is included in the sources.xml file (Fig. 24.24).
Outline
sources.xml
Fig. 24.24 | VideoSelector's list of video sources.
2009 Pearson Education, Inc. All rights reserved.
91
1 // Fig. 24.25: VideoSelector.xaml.cs
2 // VideoSelector lets users watch several videos (code-behind).
3 using System;
4 using System.Linq;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Media;
8 using System.Xml.Linq;
9
10 namespace VideoSelector
11 {
12 public partial class VideoSelectorPage : UserControl
13 {
14 private MediaElement currentVideo = new MediaElement();
15
16 // constructor
17 public VideoSelectorPage()
18 {
19 InitializeComponent();
20
• The code-behind file is shown in Fig. 24.25.
Outline
VideoSelector.xaml.cs
(1 of 4 )
Fig. 24.25 | VideoSelector lets users watch several videos(code-behind). (Part 1 of 4.)
2009 Pearson Education, Inc. All rights reserved.
92
21 // sources.xml contains the sources for all the videos
22 XDocument sources = XDocument.Load( "sources.xml" );
23
24 // LINQ to XML to create new MediaElements
25 var videos =
26 from video in sources.Descendants( "video" )
27 where video.Element( "uri" ).Value != string.Empty
28 select new MediaElement()
29 {
30 Source = new Uri( video.Element( "uri" ).Value,
31 UriKind.RelativeOrAbsolute ),
32 Width = 150,
33 Margin = new Thickness( 10 ),
34 IsMuted = true
35 };
36
37 // send all videos to the ListBox
38 previewListBox.ItemsSource = videos;
39 } // end constructor
40
Outline
VideoSelector.xaml.cs
(2 of 4 )
Fig. 24.25 | VideoSelector lets users watch several videos(code-behind). (Part 2 of 4.)
Use LINQ to get each video element from the XML file.
Define the XDocument that loads sources.xml.
UriKind.RelativeOrAbsolute argument for the MediaElement’s source allows us to prepare for either type of URI since we will not know which is being used until runtime.
Setting a MediaElement’s IsMuted property to true mutes its audio.
2009 Pearson Education, Inc. All rights reserved.
93
41 // when the user makes a new selection
42 private void previewListBox_SelectionChanged( object sender,
43 SelectionChangedEventArgs e )
44 {
45 fadeOut.Begin(); // begin fade out animation
46 } // end method previewListBox_SelectionChanged
47
48 // change the video if there is a new selection
49 private void fadeOut_Completed( object sender, EventArgs e )
50 {
51 // if there is a selection
52 if ( previewListBox.SelectedItem != null )
53 {
54 // grab the new video to be played
55 MediaElement newVideo =
56 ( MediaElement ) previewListBox.SelectedItem;
57
Outline
VideoSelector.xaml.cs
(3 of 4 )
Fig. 24.25 | VideoSelector lets users watch several videos(code-behind). (Part 3 of 4.)
2009 Pearson Education, Inc. All rights reserved.
94
58 // if new video has finished playing, restart it
59 if ( newVideo.CurrentState == MediaElementState.Paused )
60 {
61 newVideo.Stop();
62 newVideo.Play();
63 } // end if
64
65 currentVideo.IsMuted = true; // mute the old video
66 newVideo.IsMuted = false; // play audio for main video
67
68 currentVideo = newVideo; // set the currently playing video
69 brush.SetSource( newVideo ); // set source of video brush
70 } // end if
71
72 fadeIn.Begin(); // begin fade in animation
73 } // end method fadeOut_Completed
74 } // end class VideoSelectorPage
75 } // end namespace VideoSelector
Outline
VideoSelector.xaml.cs
(4 of 4 )
Fig. 24.25 | VideoSelector lets users watch several videos(code-behind). (Part 4 of 4.)
2009 Pearson Education, Inc. All rights reserved.
95
24.7 Audio and Video (Cont.)
• The UriKind.RelativeOr Absolute argument for the MediaElement’s source allows us to prepare for either type of URI since we will not know which is being used until runtime.
• Setting a MediaElement’s IsMuted property to true mutes its audio.
2009 Pearson Education, Inc. All rights reserved.
96
24.8 Isolated Storage
• Isolated storage is used to save user-specific data associated with one or more Silverlight applications from a single domain.
• The current limit for isolated data storage on a client machine is 1 MB; however, the application may request a higher quota, which can be granted by the user.
• The isolated storage is shared among all Silverlight applications from a given domain.
• Applications use isolated storage to store data in a virtual file system.
• Files called stores contain the information on the physical location of the data.
• The same isolated storage is used by all browsers on the client’s computer.