Navigation and Input controls are essential to making any
application work, but it is usually the media controls that really give an
application its visual appeal. Silverlight provides a diverse array of media
controls for displaying everything from basic images to the snazzy Deep Zoom
images. Let's take a look at how Silverlight's UI controls enable us to display
media in our beta applications.
Image
How do you display an image in a Silverlight application?
With the Image control, of course. And while you may be quick to dismiss the
Image control as nothing special (I did), there are some interesting properties
on this control you should be aware of, especially if you're coming from the
web world. First, make a mental note: Silverlight only
supports JPEG and PNG images. Sorry GIF purists, you're currently out of
luck. If you try to use a GIF image in Silverlight, an application exception
will be thrown.
To display an image, you need to set the Source
property of the Image control. The Source property can be set to one of two
things: the relative path to an image located in your Silverlight project or to
an instance of the BitmapImage class set in the code behind. If you try to set
the source directly to an image on the web (like, http://www.something.com/images/myimage.png)
Silverlight will crash. For scenarios like that, you can use the BitmapImage in
your code behind to build a new image based on a URI or stream.
Listing 20 shows a basic image control in a Silverlight
application displaying an image located in the Silverlight project. When the
project is built, the image is packaged in to the Silverlight XAP file
(basically a ZIP archive with the Silverlight specific .xap extension that
represents a deployable Silverlight application), so you don't have to worry
about deploying your images separately from your Silverlight application.
Listing 20 - Silverlight Image
<Image Stretch="None" Source="images/anxious.jpg"></Image>
Listing 20 also highlights another unique property of the
Image control: Stretch. You can set this to one of four
enumerated values: None, Fill, Uniform, or UniformToFill. Clearly,
"None" is the default value and it renders an image in its original
dimensions. The other values will stretch the image, proportionally or not, to
fill its parent container.
Also, don't forget about some of the Image controls
inherited properties, like Opacity. By setting this
value to anything less than 1 you can easily make your image translucent.
Pretty cool! Now if only other image transformations were so
easy…Image.AutoCrop().FixColor().MakeInteresting(). Maybe in Silverlight 3.0.
MediaElement
While the Image control is used for displaying static
images, the MediaElement UI control is your tool of choice for
"displaying" audio and video clips in your Silverlight app. It has a
number of unique properties and events that allow you to take control over your
media and handle downloading/buffering. Going in depth on these properties is
an article unto itself, but at the highest level you need to know that, like
the Image control, the MediaElement exposes a Source property that must be set
to the URI of your content.
The MediaElement only supports Windows
Media Video, Windows Media Audio, and MP3 formats (of varying flavors). The control also offers
support for streaming if you're using a Windows Media Streaming server and
limited support for Advanced Media Redirector (a.k.a. Windows Media metafiles)
files. Neither of these extends Silverlight's format support, but they give you
more control over how you distribute your media.
Listing 21 shows a basic MediaElement control hosting a
sample Windows Media Video. Unlike the Image control, videos won't
automatically get packaged in to your XAP file, which can cause some headaches
when you first start playing with the control. Instead, you need to manually
copy your video files to the ClientBin directory in your website for the
MediaElement to find them (in the following example, WindowsMedia.wmv is in the
root of ClientBin).
Listing 21 - Silverlight MediaElement
<MediaElement Source="WindowsMedia.wmv" AutoPlay="True" Opacity=".7">
</MediaElement>
The MediaElement also has support for Triggers. Triggers are
essentially "bookmarks," or "chapters," that you can define
for any media in the MediaElement. Typically you'd configure these ahead of
time and embed them in the media (with a program like Windows Media File
Editor), but you can create them dynamically be defining a collection of
TimelineMarkers and passing them to the MediaElement's Markers
property. Regardless of when they're created, each time a marker is reached
during media playback the MediaElement's MarkerReached event fires, giving you
the opportunity to create rich media playback environments.
MultiScaleImage
The MultiScaleImage control is perhaps the worst named
control in the current Silverlight 2 UI controls collection. The control is
really the required front-end tool for taking advantage of Silverlight's new
Deep Zoom technology (formerly Sea Dragon in MS Labs). Deep Zoom enables you to
display HUGE images on the web in a ZUI (zoomable user interface) with smooth,
animated transitions that give the illusion of seamless image zooming.
Deep Zoom images are created using a tool called, aptly, the
Deep Zoom Composer. The tool takes a large image (or multiple large images) and
processes them in to many smaller image "tiles" that are organized in
number of folders. Each folder represents a different "layer" in the
final composition. It is this collection of folders and image tiles that the
MultiScaleImage references and pieces together for you in your Silverlight
application.
To configure the MultiScaleImage, you simply set the Source property to location of the .bin file generated by the
Deep Zoom Composer. You'll need to make sure you copy all of the folders to
your ClientBin directory (or wherever you chose to host your files) in addition
to the .bin file. In Listing 22, the .bin file is in the
"ToddPortrait1_vandalized" directory, which is in the root of
ClientBin and also contains all of the Deep Zoom generated content. If
everything is configured correctly, you should see your image "zoom
in" to view when your application loads.
Listing 22 - Silverlight MultiScaleImage
<MultiScaleImage Source="ToddPortrait1_vandalized/info.bin"
ViewportWidth="1.0" Width="300" Height="300">
</MultiScaleImage>
The ViewportWidth property, set to
"1.0" in Listing 22, controls the MSI's zoom factor. The default
value is 1, which means the image will be displayed at a size that fits
everything on the screen. The closer the number supplied to ViewportWidth gets
to zero, the more zoomed the image will be. In other words, if we simply change
the ViewportWidth to ".5" instead of "1.0," when the image
loads it will be more zoomed-in (Listing 23). You can also set numbers larger
than 1, but as you do the image will simply appear smaller on the page. A
little backwards and confusing, I know.
Listing 23 - ViewportWidth zoomed
You can also set the ViewportOrigin
property, which obviously adjusts where the image is focused when it loads.
That helps you solve problems like the focus of the image above. There is also
a UseSprings property that you'll discover on the MSI
control. This enables you to disable the Deep Zoom animations- a big part of
what makes the technology "sing"- so you'll probably rarely find a
reason to set this to false.