Editor's Note: This article is written
about Silverlight 2.0 Beta 1. Topics covered in this article may change in
newer versions of Silverlight.
With the introduction of Silverlight 2.0 beta 1 at MIX08 in
March, the infant Silverlight platform took a big step forward. It now has rich
support for data binding. It has a vastly increased subset of WPF's UI engine.
It even has radical new technologies like Deep Zoom. But most importantly, Silverlight
2.0 beta 1 introduces a brand new collection of built-in UI controls.
The new UI controls are not a surprise, but they are a key
milestone in Silverlight's maturation. Microsoft has always shipped platform
technologies with a collection of built-in controls, and beta 1 ushers in that
era for Silverlight. Developers evaluating the platform as an alternative to
building applications in ASP.NET or WinForms can now seriously consider it
since it has the beginnings of the complete UI productivity toolbox.
The UI controls introduced in Silverlight 2 beta 1, though,
are unique in many ways from the controls that precede it. They are shipping
with an unprecedented licensing model (for Microsoft UI controls, that is) and
are doing many things with XAML controls that WPF has yet to produce
(eh..hem…DataGrid). In this article, we'll look at each of the 29 UI controls
that ship in Silverlight 2 beta 1 and introduce you to their features, unique
properties, and talk about some of the shortcomings in the current versions of
Silverlight 2 beta 1 ships with three built-in layout
controls: Canvas, StackPanel,
and Grid. Before the beta release, Silverlight only
provided a basic Canvas layout control, so the addition of the new StackPanel
and Grid greatly improve your ability to flexibly (or precisely) control
element position in your Silverlight application. If you've done any Windows
development (especially with WPF) the "layout container" concept
should be very familiar. If you're coming from the ASP.NET world (like me), it
takes a little more getting used to.
In short, these layout containers help you position elements
in your Silverlight application so that you don't have to manually set absolute
positions for every element on your page. As your page is resized or as you add
elements to your page, the layout containers intelligently shift things around
based on their defined behavior- work you would have to do manually otherwise.
Furthermore, these layout containers can be nested and extended, so they greatly
improve your ability to build custom UI controls or more advanced auto-layout
The Canvas layout control is the most basic, and it has been
around since the very first Silverlight versions. It provides the simple
ability to absolutely position child elements relative to the canvas' top left corner. For example, let's say we have the
following code (Listing 1) that adds a simple TextBlock to a Silverlight
Listing 1 - Canvas usage
<TextBlock Text="This is text on a blank canvas."
Canvas.Top="50" Canvas.Left="50" />
When this code is rendered by the Silverlight plug-in, we'll
see our text positioned 50 pixels from the top of the page and 50 pixels from
the left of the page (Listing 2).
Listing 2 - Canvas with Textblock
The same result could have been achieved by simply adding a
TextBlock to the default Silverlight UserControl (with no Canvas tag). That's
because the UserControl provides a surrounding default canvas that can be used
for element positioning if no other layout controls are used. All other layout
controls are positioned relative to this default container. But be careful! The
default container can only contain one element, so you'll almost always make a
layout control the first element in your UserControl.
If I nest one canvas in another, the elements in each canvas
will remain relative to the top left of their direct parent. In other words,
elements in a canvas are not always absolutely positioned to the top left of
the page. If the origin of the canvas moves, so do
the relative locations of the contained elements on the page. Listing 3
illustrates this with a second canvas (colored red for clarity) added to first,
but shifted 75 pixels down and to the right.
Listing 3 - Nested canvas
<TextBlock Text="This is text on a blank canvas."
Canvas.Top="50" Canvas.Left="50" />
<Canvas Canvas.Top="50" Canvas.Left="50" Background="Red">
<TextBlock Text="This is text on a blank canvas."
Canvas.Top="50" Canvas.Left="50" />
Anybody notice what's missing in the image in Listing 3? If
you said the red background that's "supposed" to be filling our
second canvas, you're right. This highlights an important nuance of the Canvas
control: while it will allow you to position items "in it", it won't
automatically "expand" its background to hold the fill color. By
default a canvas has a height and width of 0 and a transparent background. If
we add height and width of 50 to our second canvas, we now see its position on
the page (Listing 4).
Listing 4 - Canvas with visible background
The StackPanel enables you to easily position elements next
to each other, both horizontally and vertically. In the web world, this is
typically the type of layout implemented with HTML and CSS, where the next item
on the page renders right where the other one stopped. It's less precise than
the Grid layout, but much more flexible for scenarios where you may not know
the user's resolution.
Let's see it in action. If you add two simple rectangles to
a Silverlight canvas, by default they'll render overlapped (Listing 5). If a
Stack Panel is used, though, the elements will automatically render next to
each other. You can change the StackPanel's rendering mode by setting the Orientation property to either Horizontal or Vertical
(default). Listing 7 shows the same rectangles in a StackPanel with Orientation
set to Horizontal.
Listing 5 - Default positioning
Listing 6 - Position with a StackPanel
<Rectangle Width="100" Height="50" Fill="Red"></Rectangle>
<Rectangle Width="50" Height="25" Fill="Green"></Rectangle>
Listing 7 - Horizontal StackPanel
<Rectangle Width="100" Height="50" Fill="Red"></Rectangle>
<Rectangle Width="50" Height="25" Fill="Green"></Rectangle>
Sure to confuse more than a few ASP.NET developers, Grid is not a datagrid. It's another layout control, most directly
comparable to the HTML table. And as you would expect from a table-esque
control, the Grid layout control allows you to precisely position your page
elements in rows and columns. The Grid supports both fixed-width columns and
"liquid" columns that fill the available space. Listing 8 shows a
basic Grid layout control with 2 columns and 3 rows, with the second column set
to a fixed width and the first liquid.
Listing 8 - Basic Grid layout control
<Grid x:Name="gridLayout1" Background="White">
As you can see from the code in Listing 8, the "*" operator is used to define liquid dimensions in
Silverlight. You can also gather that Grids are defined by collections of
ColumnDefinitions and RowDefinitions defined in the XAML. Unlike HTML tables,
though, content is not directly added to the column/row definitions. Instead,
new controls are added within the Grid's opening and closing tags and are then
positioned by setting Grid.Column and Grid.Row
dependency properties (both of which will default to 0). Listing 9 shows the
new Grid XAML with TextBlocks added to each cell.
Listing 9 - Grid with content
<Grid x:Name="gridLayout1" Background="White">
<TextBlock Text="C1R1" Grid.Column="0" Grid.Row="0" />
<TextBlock Text="C2R1" Grid.Column="1" Grid.Row="0" />
<TextBlock Text="C1R2" Grid.Column="0" Grid.Row="1" />
<TextBlock Text="C2R2" Grid.Column="1" Grid.Row="1" />
<TextBlock Text="C1R3" Grid.Column="0" Grid.Row="2" />
<TextBlock Text="C2R3" Grid.Column="1" Grid.Row="2" />
Grids also support a number of other advanced features, like
column/row spanning (a concept borrowed from HTML tables), auto spacing, and
even proportional sizing. The last feature is pretty cool because it allows you
to set the width of a column to, let's say, "3*" and the column will
automatically scale in proportion to the other columns (3:1 ratio). If only it
were so elegant in HTML!
After layout controls, some of the most essential controls
in any "real world" application are input controls. They are so
common and so often used that we tend to forget their essential utility until
they are missing. Such is the case with Silverlight 1.0, where even basic
controls like buttons and textboxes are absent. Fortuantely, Silverlight 2.0
beta 1 solves that problem.
In the current beta, there is a near complete collection of
input controls, including: Button, Calendar,
CheckBox, DatePicker, ListBox, RadioButton, Slider, TexBox, ToggleButton,
and even a WatermarkedTextBox. While this is a great
start, the list is missing notable input controls common in other Microsoft
platforms like a dropdownlist/combobox, rich textbox, image button, and upload
control. While some of these may be added in subsequent betas, you can fully
bet the 3rd party component makers, like Telerik, will fill-in the gaps.
Most of the new input controls included in Silverlight are
fairly standard and will feel just like their ASP.NET and WinForms
counterparts. Nonetheless, let's take a look at each so you can see what the
markup looks like how each control renders in the browser.
Button & ToggleButton
One of the most basic and fundamental input controls is the
button. Many applications would be rendered useless without at least one button
doing something, so you'll probably end-up using this control (or controls
derived from it) a lot. Listing 10 shows the basic
XAML required to add a button to your Silverlight application and shows the
Listing 10 - Default button
<Button Width="80" Content="Push Me"></Button>
Notice that the button's text is set via the Content property, not a "Text" property. This
change was made to reflect the concept that a Button (or almost any Silverlight
control) can render more than simple text strings. You can render almost
anything on a button, including images, videos, and, of course, simple text-
thus the generic "Content" property. If you want to render more
complex content to a button, you can use the button's ContentTemplate,
which allows you to add a layout control to the button's content area and take
full control of the rendered output. This helps overcome the absence of
controls like image buttons. Listing 11 shows a more complex Silverlight button
implementation that uses the ContentTemplate to add a shape and some text to
Listing 11 - Button ContentTemplate
<Ellipse Fill="Green" Width="15" Height="15"
<TextBlock Text="Push Me" Grid.Column="1"
The Button control, like most Silverlight controls, also
provides a ClickMode property that lets you define when a click event fires: mouse hover, mouse down, or mouse
up. It's a new way for web developers to think, but familiar territory for
Meanwhile, the ToggleButton is simply a tri-state button
control. That means it has a normal state, a clicked state, and an in-between
"toggled" state. It's not very common in standard web applications,
but the concept is simple to grasp. All features of the regular Silverlight
Button are supported by the ToggleButton.
Calendar & DatePicker
A little more complex than a basic button, the Calendar
control serves the universal purpose of helping users visualize and provide
DateTime information. And directly related, the DatePicker control simply takes
a Calendar and automatically attaches it to a Textbox so that it's easy for you
to collect date input. The Calendar/DatePicker in Silverlight more closely
resemble the rendering and features of an ASP.NET calendar than the terrible default calendar than comes with WinForms, so this
territory will be more familiar for web developers than Windows developers.
The Calendar control has a number of unique properties that
customize the control's behavior, including AreDatesInPastSelectable,
and SelectableDateEnd/Start. Most of these properties
expose their behavior through their naming, so little explanation is needed.
The Calendar control is not as full featured as most 3rd party calendar
controls currently available for other Microsoft platforms, but is a much
better "basic" starting point than Microsoft has provided in the
Listing 12 shows a basic Silverlight Calendar in both Month
and Year DisplayModes. Also shown is the Silverlight DatePicker in both
collapsed and expanded states.
Listing 12 - Basic Silverlight Calendar
<Calendar DisplayMode="Month" FirstDayOfWeek="Monday"></Calendar>
CheckBox & RadioButton
CheckBoxes and RadioButtons are universally recognized,
common in many applications, and essential parts of the Silverlight UI control
set. The Checkbox and RadioButton in Silverlight very closely resemble their
HTML/ASP.NET counterparts, both in functionality and property naming. The
controls share the Content property for defining the
elements that will be rendered next to the checkbox/radiobutton and also share
the IsThreeState property. The IsThreeState property
enables the CheckBox and RadioButton to operate as tri-state controls, similar
to the functionality of the ToggleButton.
The CheckBox has one unique property called IsChecked. Just as in ASP.NET, this property enables you to
programmatically set the checkbox's selected state. Meanwhile, the RadioButton
has the unique GroupName property, which is used to
define which radiobuttons will be toggled when a selection is made. Listing 13
shows both of these controls and their default rendering.
Listing 13 - Silverlight CheckBox and RadioButton
<CheckBox IsChecked="True" IsThreeState="True" Content="Checkbox" />
<RadioButton GroupName="rb" Content="RadioBtn1" />
<RadioButton GroupName="rb" Content="RadioBtn2" />
The ListBox control is a very flexible UI control in
Silverlight that makes it easy to display lists of data. It is similar to the
ASP.NET ListBox, but much more flexible thanks to Silverlight's XAML
underpinnings that allow anything to be rendered in each list item (via the ContentTemplate property). The ListBox accepts a collection
of ListBoxItems to define items, and it will automatically render scrollbars if
the content is larger than the ListBox dimensions. Listing 14 shows the ListBox
Listing 14 - Silverlight ListBox
<ListBox Width="150" Height="80">
<ListBoxItem Content="Item 1" />
<ListBoxItem Content="Item 2" />
<ListBoxItem Content="Item 3" />
<ListBoxItem Content="Item 4" />
<ListBoxItem Content="Item 5" />
<ListBoxItem Content="Item 6" />
If you are binding data to your ListBox control, you bing
the collection to the ItemSource property (similar to
the DataSource property on ASP.NET controls). The collection can be anything
that implements IEnumerable, so the binding support is very flexible. You can
also use the SelectedItem and SelectedIndex
properties to identify items that users select.
Slider is not a standard control in the ASP.NET developers
default toolbox, though many free and 3rd party implementations exist to fill the
gap. With Silverlight, the tool is built-in to the platform and immediately at
As far as the implementation goes, it's a pretty standard
control with support for vertical and horizontal rendering, setting minor and
major ticks, and setting slider range values. The most serious missing
"feature" is support for the mouse scroll wheel, though technically,
that's a Silverlight platform problem (Silverlight doesn't currently support
the scroll wheel, though workarounds do exist). Hopefully future versions of
the platform will fix this problem. In the mean time, keyboard support abounds
and the control's rich event model will enable you to do a lot of fun things in
Listing 15 shows the default Slider control rendering. You
can click and drag the slider, click anywhere on the slider "bar", or
use the keyboard to change the slider's value.
Listing 15 - Silverlight Slider
<Slider IsDirectionReversed="True" Width="200"
Minimum="0" Maximum="100" />
Some of the Slider's unique properties are illustrated in
Listing 15, such as SmallChange, LargeChange, Minimum, and Maximum. The Min and
Max properties obviously set the value range that the slider represents, and
the Change properties dictate how many units the slider will move per
interaction. Clicking on the Slider track will trigger a "large"
change; using the keyboard will trigger "small" changes.
TextBox & WatermarkedTextBox
Controls don't get much more basic than a TextBox (a
rectangle that accepts text), and Silverlight doesn't do much to innovate on
the tried and true basic. There are two flavors of TextBox in Silverlight 2
beta 1: regular and watermarked. Both share the exact same feature set with the
key exception that the WatermarkedTextBox has an extra Watermark
The only unique feature of the current TextBox is that it
now supports line breaks, so you can employ a simple multi-line textbox. Other
than that, there is no rich text editing support provided with the current
textbox controls. This could present a real challenge for web scenarios where
developers are used to working with formatted HTML.
Listing 16 shows both variants of the Silverlight textboxes
and the required XAML.
Listing 16 - Silverlight Textbox and
<TextBox Text="Some text" Width="200" />
<WatermarkedTextBox Watermark="Enter text" Width="200" />
Your users won't get very far if they can't traverse your
application, and that's where the Silverlight navigation controls come in to save
the day. There are only a couple of controls I consider "navigation"
controls in the current Silverlight 2 beta 1, though some of the Input controls
we've already looked at (like the button) could also be used for navigation.
The controls we'll look at in this section- HyperlinkButton, ScrollBar, and
ScrollViewer- can all be used to help users navigate through
your application or navigate your content. Let's see how they work.
The HyperlinkButton is a familiar carryover from the ASP.NET
world and it serves the primary purpose of making it easy to link to other
URLs. The HypelinkButton exposes all of the "standard" Silverlight
button properties with one key addition: the NavigateUri
property. To use the control, you can simply set this to a valid Uri and
Silverlight will automatically redirect you to that location. Listing 17 shows
a simple implementation of the HyperlinkButton. Notice that by default it
renders in blue (standard link usability on the web), but it does not underline by default (hovered or unhovered). This is
something you may want to address manually to make your Silverlight application
more user friendly on the web.
Listing 17 - Silverlight HyperlinkButton
<HyperlinkButton NavigateUri="http://www.google.com" Content="Click Me" />
The NavigateUri property cannot be used to
"navigate" to different XAML pages in your Silverlight application. If
you try to pass a relative XAML location to this property (like, let's say,
page2.xaml), Silverlight will throw an exception.
ScrollBar & ScrollViewer
The ScrollBar and ScrollViewer controls, unlike the
Hyperlink, are familiar carryovers from the WinForms world. The ScrollBar
control provides a flexible implementation of a scrollbar that you can use for
any number of purposes, not just scrolling content. In essence, it is Slider
control with RepeatButtons automatically rendered on either end of the track.
The ScrollViewer, meanwhile, is more focused on delivering support for
scrolling content. It is actually composed with ScrollBar controls internally,
so it is not adding any new scrolling features that the ScrollBar doesn't
offer. In fact, the ScrollViewer loses a few important features, like the
ScrollBar's usefull Scroll event, so make sure you pick the control that best
suits your needs.
As far as unique properties go, the ScrollBar exposes a few
important properties that enable you to control scrolling behavior. The
properties are very similar to those on the Slider control, such as Maximum, Minimum, LargeChange,
SmallChange, and Orientation.
The purpose of these properties should be pretty self-evident- set a ScrollBar
value range, the size of ScrollBar steps when clicked (large steps occur when
the track is clicked, small steps when the buttons are clicked), and the
Horizontal or Vertical orientation of the ScrollBar. More interesting is the ViewportSize property. This property allows you to tell the
ScrollBar how much of the scrollable "content" is visible so that the
"thumb" (the movable scrollbar) can be sized appropriately. The larger
that you make the ViewportSize value, the wider the thumb will be.
The ScrollBar also exposes two helpful events: OnScroll and OnValueChanged. Both of
these events allow you to respond to user interaction with the ScrollBar and
both are missing in the ScrollViewer control by default. There are ways to
"hack" these events in to the ScrollViewer, and future versions may
even expose these events by default, but for now this is one of the key
shortcomings of the ScrollViewer control.
Listing 18 shows a basic ScrollBar control with a few of its
"unique" properties set. Notice that the width of the ScrollBar's
thumb is wider than default thanks to the value supplied to ViewportSize.
Listing 18 - Silverlight ScrollBar
<ScrollBar Width="200" Orientation="Horizontal"
Maximum="200" Minimum="1" ViewportSize="50"
LargeChange="50" SmallChange="1" />
Meanwhile, the ScrollViewer control is specifically designed
to enable scrolling of content. Most Silverlight UI controls expose
ScrollViewer dependency properties, but you can also manually add a
ScrollViewer to your application. Since the ScrollViewer is dedicated to
scrolling content, it does not provide Minimum, Maximum, Large/SmallChange, or
Value properties. Instead, it provides Horizontal/VerticalScrollBarVisibility
properties that can be set to one of four values: Auto, Disabled, Hidden, or
Visible. Listing 19 shows the ScrollViewer in action with a TextBlock in the
Viewer's content area.
Listing 19 - Silverlight ScrollViewer
<ScrollViewer Width="200" Height="50"
Text="Some text in a TextBlock in the ScrollViewer" />
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.
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.
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">
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.
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
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
ViewportWidth="1.0" Width="300" Height="300">
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.
So far we've seen a lot of "basic" controls
built-in to Silverlight's UI control toolbox. Buttons, textboxes, hyperlinks,
images, and the like are all relatively basic controls that form the foundation
of any application UI. What we haven't seen are more
advanced or complex controls like a treeview, tabstrip, panelbar, scheduler, or
the ever popular carousel. As of Silverlight 2 beta 1, these controls simply
aren't present and time will reveal which get included by Microsoft and which
will depend on the 3rd party UI market to supply. For now, the only complex
control in Silverlight is the DataGrid, so let's take a look at how it works.
DataGrids are fundamental UI controls for almost all line of
business (LOB) applications. They radically simplify the task of displaying
structured data to users by automatically handling the rendering of rows,
columns, headers, and data navigation. Silverlight's data grid is no exception.
While it is far from being a complete or "advanced" grid control by
today's WinForms and ASP.NET standards, it does provide basic grid
To use the DataGrid control, you must simply bind the Grid
to a list of items (that implement IEnumerable) via the ItemSource property. In
the simplest approach, the Grid will automatically generate columns based on
the data you supply and even render "special" column types- like
checkbox columns- based on your data types. You can, of course, take more
control and manually define the columns that will be rendered in your grid by
setting the AutoGenerateColumns property to false.
Listing 24 shows a simple Silverlight DataGrid that is bound
to data supplied by a WCF web service. The Grid is bound in the XAML page's
code-behind by simply supplying the list of items returned by the WCF web
service to the Grid's ItemSource property. Things to notice in listing 24 are
the checkbox column automatically generated for Boolean data and that the Grid
has the built-in ability to allow users to resize columns.
Listing 24 - Silverlight DataGrid
<my:DataGrid x:Name="dataGrid1" AutoGenerateColumns="true">
void proxy_GetPeopleCompleted(object sender,
this.dataGrid1.ItemsSource = e.Result;
Unlike all of the other UI controls you've seen so far, the
DataGrid UI tag is prefixed by the odd "my" name. That's because the
DataGrid does not exist in the default Silverlight namespace. You need to add
the namespace in Listing 25 to your XAML document in order to use the
Silverlight DataGrid control. The "standard" name you'll find
assigned to this namespace in most Silverlight demos is "my," but you
could name this namespace whatever you like (producing
Listing 25 - DataGrid namespace
The DataGrid already exposes a number of properties that
enable you to customize its appearance and behavior. Among the most significant
are AlternatingRowBackground, CanUserResizeColumns,
RowBackground, and SelectionMode.
That last property, SelectionMode, allows you to control how rows can be
selected. Setting the value to SingleFullRow will only allow one row to be
selected at a time; setting it to ExtendedFullRow allows users to select
multiple rows by using the shift and control keys.
While the DataGrid in Sivlerligth 2 beta 1 is a great
addition to the framework, it is still a far, far cry from providing the level
of functionality we as developers have come to expect from datagrid controls.
For example, the current DataGrid provides no out of the box support for sorting,
grouping, filtering, or hierarchal data display. Paging isn't even a supported
concept as all data is currently rendered and then scrolled (as is usually done
in WinForms). Since Silverlight is going to attract web developers, I expect
many will view this approach to paging as a shortcoming, too.
Data editing is another soft spot. The Grid does support
basic inline editing, but advanced modes like form editing and pop-up window
data editing are absent. For Windows developers, this probably isn't a problem;
for web developers, this is another road block. That is a repeating theme in
Silverlight that could pose problems for both Microsoft and UI component
vendors that build for Silverlight. What type of developer do you try to please:
traditional web developers migrating towards richer web experiences or
traditional WinForms developers trying to build apps that can be distributed
via the browser? Each group has vastly different expectations of how UI
controls should behave, so it will be interesting to see which UI concepts win-out
At the end of the day, there are a few controls that don't
cleanly fit in to the other categories. Call these controls "utility"
controls or "bonus" controls or whatever you like, but this wouldn't
be a complete introduction of all Silverlight 2.0
controls if we didn't briefly give them some attention.
ToolTip, while basic, is a neat little utility control that
allows you to attach attractive ToolTips to just about anything in a Silverlight
application. And since they're provided by the plug-in (and not the browser),
you have the ability to take complete control over their styling and content.
Listing 26 shows a simple ToolTip attached to a TextBlock providing users
context when they hover over the element.
Listing 26 - Silverlight ToolTip
<TextBlock Text="Howdy Silverlight" control:ToolTipService.InitialShowDelay="500">
<ToolTip HorizontalOffset="10" VerticalOffset="10"
Content="Here's a tip..." />
Normally, a TextBlock doesn't expose a ToolTip property
(like, say, a Button does). That's where the ToolTipService
comes in to play (seen in Listing 26). Aside from giving you control (in
milliseconds) over InitialShowDelay, ShowDuration,
and BetweenShowDelay (as in, how long until the tip is
displayed again), the ToolTipService also enables you to attach ToolTips to
objects that don't expose them by default. To use the ToolTipService in
Silverlight 2 beta 1, though, you'll need to add an extra namespace reference
to your XAML page since the Service is not built-in to the core Silverlight
assembly (unlike ToolTip). Listing 27 shows you the code that you need to add
to your page.
Listing 27 - ToolTipService namespace reference
You may have also noticed in Listing 27 the HorizontalOffset
and VerticalOffset properties. These properties specify the offset distance in
pixels relative to the cursor, not the control. At
present there is no way to change other aspects of the tip's display, such as
making the position relative to the object vs. the mouse or making the tip
display on the left vs. the right. You'll have to wait for 3rd party controls
to give you that level of control (for now).
Equivalent to the ASP.NET Label control, the TextBlock is
your run of the mill read-only text control. Like the Silverlight TextBox, it exposes a Text property
that enables you to set its contents (vs. the more common Content property).
Beyond that, there is nothing too special about the
TextBlock and you should find it very easy to use. Listing 28 shows the
TextBlock "in action"- very dull action.
Listing 28 - Silverlight TextBlock
<TextBlock Text="Howdy Silverlight"></TextBlock>
The only other properties worth mentioning are TextWrap, LineHeight, and LineStackingStrategy, all of which are somewhat related. When
TextWrap is set to "Wrap" (NoWrap is default), Silverlight will start
wrapping text on to multiple lines when it is longer than the controls defined
width. And don't expect Silverlight to look for word breaks- it will wrap in
the middle of a word if that's where the length constraints hit. In any event,
when Silverlight wraps, by default it will set a line height that accommodates
the text and stack each line with no overlap.
If you want more control, you can manually set the
LineHeight and then set the LineStackingStrategy to one of two values:
MaxHeight or BlockLineHeight. MaxHeight closely imitates the default settings
in that it won't allow text to overlap, even if you've set a smaller
LineHeight. Changing the LineStackingStrategy to BlockLineHeight, though, will
allow text to overlap giving precedence to the LineHeight setting. Listing 29
shows two identical TextBlocks with LineHeight set to 10. The only difference
is the LineStackingStrategy property, and you can clearly see the impact on
text positioning. In the design world, we call this type of "line spacing"
Listing 29 - LineStackingStrategy
<TextBlock Text="Howdy Silverlight" TextWrapping="Wrap"
LineStackingStrategy="<span class=Bold>MaxHeight</span>" Width="50"
<TextBlock Text="Howdy Silverlight" TextWrapping="Wrap"
LineStackingStrategy="<span class=Bold>BlockLineHeight</span>" Width="50"
Border is another poorly named Silverlight UI control. With
its current name, it is easy to think of it as some kind of
"extension" control that enables you to add borders to other controls
(like rectangles or TextBoxes). In reality, it is a control that enables you to
draw boxes in your Silverlight application, similar to HTML fieldsets (a better
name in my opinion). The Border control is actually a lot like the HTML
fieldset because it also allows you to add other Silverlight controls directly
to its contents. This is a much more convenient way to wrap elements in a box than
trying to manually position everything in a rectangle on your page (the
Listing 30 shows a Border control with a simple TextBlock
contained. Note the CornerRadius property set in the
example. This property makes it very easy to round the corners of your Border
box. It's a much more direct approach than the RadiusX and RadiusY properties
supplied by the XAML rectangle, though clearly less configurable.
Listing 30 - Silverlight Border Control
<Border BorderThickness="3" BorderBrush="Black" Width="200"
<TextBlock Text="I'm in a 'Border'" />
Since Silverlight is based on XAML, you'll find it a lot
easier to do basic drawing and manipulation of shapes that you do in the GDI+
worlds of ASP.NET and WinForms. Silverlight defines a number of simple shapes,
such Ellipse, Rectangle, and Line. Shapes can be almost infinitely styled, so
it's up to you and your imagination (and mastery of XAML…or Expression Blend)
to make Shapes work for you. Listing 31 shows a simple Rectangle with a solid
brush fill and an Ellipse with a gradient brush with the required XAML. How
many lines of code would it take to do this with GDI+ in ASP.NET? A lot more.
Listing 31 - Silverlight Shapes
<Rectangle Fill="Red" Width="200" Height="100" />
<Ellipse Width="100" Height="50">
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="LightGreen" Offset="0" />
<GradientStop Color="Black" Offset=".5" />
<GradientStop Color="White" Offset=".8" />
Silverlight 2 beta 1 has introduced a lot of essential UI
controls to the infant web platform, but there is much more that needs to be
done to make Silverlight "complete." From a more complete collection
of built-in controls to a robust and functioning 3rd party market, Silverlight
has some work ahead of it to become an equal peer among stalwarts like WinForms
and ASP.NET. There are three key areas in Silverlight's UI component model that
need improvement: More advanced controls, 3rd party support, and better data
While the first beta of Silverlight 2 does ship with a
DataGrid control, it is lacking many of the other "complex" controls
that are required to build complete line-of-business (LOB) apps. Controls like
treeviews, tabstrips, menus, rich text editors, and schedulers are all absent
in the current preview. Some of these controls may be added by Microsoft in the
next two betas, but if history is any indication, there will be gaps in
Part of the challenge with Silverlight and its requirement to
provide vast collection of controls is that it is trying to appeal to two
distinct developer groups: Windows developers that want to build their apps for
the web and web developers that want more rich "desktop-like"
experiences in their web apps. Each group is used to a different
"default" collection of controls, so it is going to be very hard for
Microsoft to please everyone. All the more reason the next point is important.
3rd Party Support
Every successful Microsoft development platform has been such
due in part to rich 3rd party support, especially in the UI control arena.
Microsoft recognizes that it can't (and doesn't want) to please everyone and
they rely on the symbiotic relationship with component vendors to address the
needs of a diverse development community. Silverlight is no exception.
As Silverlight moves past its first beta and approaches RTM
near the end of summer 2008, UI component vendors (like Telerik, DevExpress,
etc.) will start to ship complete toolboxes of controls built for the new
platform. And while it's good to know that's coming, production versions of 3rd
party UI controls are still months away. It's an important consideration to
keep in mind when debating any Silverlight development this year. Just imagine
how productive you'd be without your favorite UI component set in your current
Data Access Support
Finally, Silverlight has a long way to go to make data
access a more intuitive process. Silverlight beta 1 has none of the traditional
"data source" controls we've grown to expect in Microsoft's
development platforms, so building a "quick" proof-of-concept
Silverlight application that accesses a SQL Server database is no trivial task.
At present, it requires (at least) a web service to serve the data from your
web server to your Silverlight application running in the browser.
There are solutions on the horizon, like the Astoria
project, that promise to ease the pain, but Microsoft has no published plans to
add data source controls to Silverlight (or WPF, for that matter). Some
Microsoft insiders have blogged about the possibility
of data source controls in the future, but at this point it's nothing more than
ideas. The only way to ensure Microsoft spends enough time on this problem is
if they get clear feedback from the community- a.k.a. you! If you want data
access in Silverlight to be easier, let Microsoft know.
Phew! If you've made it this far you are now a virtual
expert on the controls included in Silverlight 2.0 beta 1. Hopefully you've
found this information helpful and informative, and as you start making
decisions to build "real world" Silverlight applications this
information will give you the confidence you need to effectively evaluate the
new platform. Silverlight still has a ways to go to be on par with mature
platforms like WinForms and ASP.NET, but clearly it is making-up ground
A complete set of UI components is essential to making any
development platform a productive environment, and beta 1 finally moves
Silverlight closer to "development ready." Whether or not the current
state is enough for your needs is obviously up to you to determine, but with
this article under your belt, your choice should be a lot clearer.