Page view counter

Silverlight Toolkit November 2008 Overview

Hi folks,

 

We’ve just shipped the first release of the Silverlight Toolkit’s on http://codeplex.com/Silverlight.

HelloWorld1

HelloWorld2

HelloWorld3  

HelloWorld4

 

I’d like to do a 101 technical overview of these controls in this blog post.

During the next few days I’ll publish technical deep dives on each control, but for now, we’re sticking to an overview.

 

TreeView 

TreeView

<controls:TreeView Width="150" Height="200">

    <controls:TreeViewItem Header="You" IsExpanded="True">

        <controls:TreeViewItem Header="Work" IsExpanded="True">

            <controls:TreeViewItem Header="Silverlight" IsExpanded="True"/>

        </controls:TreeViewItem>

        <controls:TreeViewItem Header="Life" IsExpanded="True">

            <controls:TreeViewItem Header="Family"/>

            <controls:TreeViewItem Header="Friends"/>

        </controls:TreeViewItem>

    </controls:TreeViewItem>

</controls:TreeView>

 

Let’s review what’s going on here.

We’ve nested some TreeViewItems in one another (Which implicitly set the TreeView.Items property) and set TreeView.IsExpanded=True to show those children up once the Treeview loads. One more interesting thing we’ve done is set the TreeView.Header property (which could have been populated with any element since it’s just Content).

 

AutoCompleteBox

AutoCompleteBox

<controls:AutoCompleteBox Width="100" x:Name="autoComplete" />

 

autoComplete.ItemsSource = new string[]

        {"You", "Life", "Work", "Silverlight", "Friends", "Family"};

 

By Setting the AutoComplete.ItemsSource we’ve told the AutoComplete to filter out items from this list of items.

In future blog posts we’ll see how we can change the display of the drop down and the filtering behavior.

 

NumericUpDown

NumericUpDown

<input:NumericUpDown Width="100" Height="30" Increment="1" IsEditable="True" Maximum="100" Minimum="0" Value="33" DecimalPlaces="1"/>

 

The property names are pretty self explanatory. Interesting to note is the NumericUpDown.DecimalPlaces property that let’s you define how many decimal places after the dot you’d like to show in your NumericUpDown.

 

DockPanel

DockPanel 

<Border Height="Auto" Width="Auto" BorderBrush="#FF000000" BorderThickness="1,1,1,1" >

    <controls:DockPanel Height="150" Width="200" LastChildFill="True">

        <Image Source="You.png" controls:DockPanel.Dock="Left" Stretch="None"/>

        <Image Source="Work.png" controls:DockPanel.Dock="Right" Stretch="None"/>

        <Image Source="Family.png" controls:DockPanel.Dock="Top" Stretch="None"/>

        <Image Source="Friends.png" controls:DockPanel.Dock="Bottom" Stretch="None"/>

        <Image Source="Life.png" Stretch="None" />

    </controls:DockPanel>

</Border>

To begin with, you can see that the DockPanel is surrounded with a <Border /> just so we could see the edges of the DockPanel.

Next you can see that each Image is placed in it’s original size on the DockPanel and each Docked with the DockPanel.Dock Attached Dependency property to a different side.

And last, the DockPanel.LastChildFill is set to true. So the last item will be aligned to the “Center” dock. Since the image is marked as “No Stretch” it won’t expand, but it’s still aligned to center.

 

 

WrapPanel

WrapPanel

<controls:WrapPanel Orientation="Horizontal" Width="200">

    <Image Source="Life.png" Stretch="None" />

    <Image Source="You.png" Stretch="None" />

    <Image Source="Work.png" Stretch="None" />

    <Image Source="Family.png" Stretch="None" />

    <Image Source="Friends.png" Stretch="None" />

    <Image Source="Silverlight.png" Stretch="None" />

</controls:WrapPanel>

 

For those of you familiar with WrapPanel it’s pretty obvious what’s going on here – there’s a bunch of items being written sequentially  left-to-right and than to the next row.

 

Let’s test this WrapPanel out in different widths: 50, 100 and 200 pixels width.

Same WrapPanel Width=50

image

Width=100

image

 

Width=150

image

And finally Width=200.

WrapPanel

The interesting thing about this sample is that it’s aligned Left-to-Right because we’ve set WrapPanel.Orientation=Horizontal.
We could have changed it to Vertical so the WrapPanel would place items top-to-bottom.

 

 

ViewBox

Viewbox 

<controls:Viewbox Height="50" Width="20">

    <Image Source="StickMan.png" Height="100" Width="40"/>

</controls:Viewbox>

<controls:Viewbox Height="100" Width="40">

    <Image Source="StickMan.png" Height="100" Width="40" />

</controls:Viewbox>

<controls:Viewbox Height="150" Width="100">

    <Image Source="StickMan.png" Height="100" Width="40"/>

</controls:Viewbox>

 

A ViewBox essentially resized content to fit it by applying a ScaleTransform.

So in the first sample, where we have a 40x100 pixels image in a 20x50 pixels viewbox – The Image would get a ScaleTransform of 0.5. (50%)

In the second sample, where the container is exactly 40x100 pixels wide, we’ll get a ScaleTransform of 1 (100%, meaning none).

And in the Third sample, where the container is 150x100 pixels wide we’ll get a ScaleTansform of all more than 1.5 (more than 150%).

 

Label

Label

<controls:Label FontSize="18">

    <StackPanel Orientation="Horizontal">

        <Image Source="You.png" />

        <TextBlock Text="I'm a Stickperson!"/>

    </StackPanel>

</controls:Label>

 

Label isn’t a really intriguing control, but it has one very appealing property. Instead of plain text, it has Label.Content property.
Which is one of the strengths of WPF/Silvelright based model in comparison to more mature ASP.Net/Winforms based models.

In this Label we’ve decided to place a TextBlock and an Image horizontally aligned inside a Label.

The beauty here is that we’ve declared the Label as Font 18 and that tunneled down all the way to TextBlock.

 

HeaderedContentControl

HeaderedContentControl

<controls:HeaderedContentControl HorizontalContentAlignment="Center">

    <controls:HeaderedContentControl.Header>

        <TextBlock Text="Your Stickfigure life" FontSize="18" TextDecorations="Underline" />

    </controls:HeaderedContentControl.Header>

    <controls:HeaderedContentControl.Content>

        <Image Source="Life.png" Stretch="None" />

    </controls:HeaderedContentControl.Content>

</controls:HeaderedContentControl>

The HeaderedContentControl has two interesting properties we’re showing off here – HeaderedContentControl.Content and HeaderedContentControl.Header.

Both of which follow the “content” model and can be set to any element.

In this sample we’ve placed a TextBlock into the Header and an Image in the Content.

 

 

Expander

image

<controls:Expander>

    <controls:HeaderedContentControl.Header>

        <TextBlock Text="Your Stickfigure life" FontSize="18" TextDecorations="Underline" />

    </controls:HeaderedContentControl.Header>

    <controls:HeaderedContentControl.Content>

        <Image Source="Life.png" Stretch="None" />

    </controls:HeaderedContentControl.Content>

</controls:Expander>

 

The Expander control inherits from HeaderedContentcontrol so it has roughly the same API.

But, it renders out a completely different control.

This is how Expander looks like once it’s loaded:

image

And with one click on the Expand button, it drops down.

image

Another click brings it back to it’s collapsed state.

image

 

HeaderedItemControl

HeaderedItemsControl

headeredItemControl.ItemsSource = new string[]

    { "You", "Life", "Work", "Silverlight", "Friends", "Family" };

 

<controls:HeaderedItemsControl x:Name="headeredItemControl">

    <controls:HeaderedItemsControl.Header>

        <TextBlock Text="Your life" FontSize="18" TextDecorations="Underline" />

    </controls:HeaderedItemsControl.Header>

    <controls:HeaderedItemsControl.ItemTemplate>

        <DataTemplate>

            <TextBlock Text="{Binding}" Margin="10 0 0 0"/>

        </DataTemplate>

    </controls:HeaderedItemsControl.ItemTemplate>

</controls:HeaderedItemsControl>

The HeaderedItemsControl is an ItemsControl that has a HeaderedItemscontrol.Header property.

we’ll set the Header property with a TextBlock.

Now, we’ve defined a HeaderedItemsControl.ItemsTemplate that basically shows us whatever you bind to it in a TextBlock with some margin.

We’ve given the sample a list of value as the HeaderedItemsControl.ItemsSource and it rendered all of those into the TextBlocks found in the ItemTemplate.

 

 

Chart - ColumnSeries

ColumnSeries

columnSeries.DataContext = new KeyValuePair<string, int>[]

                               {

               new KeyValuePair<string, int>("Work", 9),

               new KeyValuePair<string, int>("Sleep", 8),

               new KeyValuePair<string, int>("Driving", 2),

               new KeyValuePair<string, int>("Family", 4),

               new KeyValuePair<string, int>("Friens", 1),

                               };

<charting:Chart x:Name="columnSeries" Height="200" Margin="8,8,492,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="300">

    <charting:Chart.Series>

        <charting:ColumnSeries ItemsSource="{Binding}"

                              DependentValueBinding="{Binding Value}"

                              IndependentValueBinding="{Binding Key}"

                              Title="Time"  />

    </charting:Chart.Series>

</charting:Chart>

 

Let’s explain what we’re seeing and how we got to it.

First, we’ve got a Chart with a Chart.Series set to ColumnSeries. That by itself is enough t add a new ColumnSeries to the chart.

Now, we want some data in our Chart and we’ll use DataBinding magic to get it.

We’ll start off by specifying a Chart.DataContext with a collection of KeyValuePairs. Each pair has a Key and a Value.
Next, we’ll tell the ColumnSeries.DependentValue (which is the numerical value being followed on the columns) that it’s DataBound to Value.
And DataBind ColumnSeries.IndependentValue to Key.

It’s important to remember that, IndependentValue is the text that shows up on under the Column. And DependentValue is the value of the actual Column.

We’ll put the Cherry on top by specifying ColumnSeries.Title as ‘Time’. 

 

 

Chart - BarSeries

BarSeries

barSeries.DataContext = new KeyValuePair<string, int>[]

                               {

               new KeyValuePair<string, int>("Work", 9),

               new KeyValuePair<string, int>("Sleep", 8),

               new KeyValuePair<string, int>("Driving", 2),

               new KeyValuePair<string, int>("Family", 4),

               new KeyValuePair<string, int>("Friens", 1),

                               };

<charting:Chart x:Name="barSeries" Width="350" Height="250">

    <charting:Chart.Series>

        <charting:BarSeries ItemsSource="{Binding}"

                           DependentValueBinding="{Binding Path=Value}"

                           IndependentValueBinding="{Binding Path=Key}"

                           Title="Life" />

    </charting:Chart.Series>

</charting:Chart>

Very similar to the ColumnSeries example, just that in this example we’ll use a BarSeries.

 

 

Chart – PieSeries

PieSeries

pieSeries.DataContext = new KeyValuePair<string, int>[]

                               {

               new KeyValuePair<string, int>("Work", 9),

               new KeyValuePair<string, int>("Sleep", 8),

               new KeyValuePair<string, int>("Driving", 2),

               new KeyValuePair<string, int>("Family", 4),

               new KeyValuePair<string, int>("Friens", 1),

                               };

<charting:Chart x:Name="pieSeries" Width="350" Height="250">

    <charting:Chart.Series>

        <charting:PieSeries ItemsSource="{Binding}"

                           DependentValueBinding="{Binding Path=Value}"

                           IndependentValueBinding="{Binding Path=Key}"

                           Title="Life"/>

    </charting:Chart.Series>

</charting:Chart>

Again, very similar to the BarColumn Sample. We’re just using a PieSeries here.

 

 

Chart - ScatterSeries

ScatterSeries

scatterSeries.DataContext = new KeyValuePair<DateTime, int>[] {

       new KeyValuePair<DateTime, int>(DateTime.Now, 9),

       new KeyValuePair<DateTime, int>(DateTime.Now.AddDays(1), 8),

       new KeyValuePair<DateTime, int>(DateTime.Now.AddDays(2), 9),

       new KeyValuePair<DateTime, int>(DateTime.Now.AddDays(3), 6),

       new KeyValuePair<DateTime, int>(DateTime.Now.AddDays(4), 8)

    };

<charting:Chart x:Name="scatterSeries" Width="400" Height="250" >

    <charting:Chart.Series>

        <charting:ScatterSeries ItemsSource="{Binding}"

                               DependentValueBinding="{Binding Path=Value}"

                               IndependentValueBinding="{Binding Path=Key}"

                               Title="Work" />

    </charting:Chart.Series>

</charting:Chart>

 

Let’s look at the chart. It shows how many hours we’ve worked each day in the week.

The reason this Chart is different than the previous charts is that a ScatterSeries.IndepdenValue needs to be comparable.
The Chart orders items based on their relative “size” in comparison to other items. In previous examples, the order of items determined final horizontal placement. However, In this type of series, The value of the IndepdentValue determines that.

So Instead of using a string which isn’t comparable and does not work as an IndependentValue, we’re using a DataTime.

The rest is pretty similar to how we’ve worked with other charts.

 

 

Chart – Line Series

LineSeries 

lineSeries.DataContext = new KeyValuePair<DateTime, int>[] {

       new KeyValuePair<DateTime, int>(DateTime.Now, 9),

       new KeyValuePair<DateTime, int>(DateTime.Now.AddDays(1), 8),

       new KeyValuePair<DateTime, int>(DateTime.Now.AddDays(3), 6),

       new KeyValuePair<DateTime, int>(DateTime.Now.AddDays(2), 9),

       new KeyValuePair<DateTime, int>(DateTime.Now.AddDays(4), 8)

    };

<charting:Chart x:Name="lineSeries" Width="400" Height="250" >

    <charting:Chart.Series>

        <charting:LineSeries ItemsSource="{Binding}"

                            DependentValueBinding="{Binding Path=Value}"

                            IndependentValueBinding="{Binding Path=Key}"

                            Title="Work"/>

    </charting:Chart.Series>

</charting:Chart>

This is pretty similar to how we’ve worked with ScatterSeries, just that in this case we’re using a LineSeries.

A LineSeries is visually equivalent to a ScatterSeries, minus the fact that it has lines drawn between it’s DataPoints.

 

 

ImplicitStyleManager

ImplicitStyleManager

// in myPage.xaml

<UserControl theming:ImplicitStyleManager.ApplyMode="OneTime"

   theming:ImplicitStyleManager.ResourceDictionaryUri="projectName;compoent/Theme.xaml" >

    <Button Content="Hello Stickperson!" Canvas.Top="170" Canvas.Left="191" />

</UserControl>

// in Theme.xaml

<ResourceDictionary

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >

    <Style TargetType="Button">

        <Setter Property="FontSize" Value="22" />

        <Setter Property="Foreground" Value="Blue" />

    </Style>

</ResourceDictionary>

 

As you can see, in Theme.xaml we’ve got a default style for Button. A default style basically means “we want all controls of type X to receive style Y as default”.

In this specific sample we want all Buttons by default to be Font size 22 and foreground color Blue.

 

Now in this sample ImplicitStyleManager takes the Theme.xaml file, loads it up and applies it to all the children of UserControl.
We instructed it to do that by specifying an ImplicitStyleManager.ResourceDictionaryUri property with the full resource URI for Theme.xaml. And we made sure Theme.xaml has a built action set to Resource.

We’ve also specified ImplicitStyleManager.ApplyMode=OneTime which just means that we want the styles to be applied on the UserControl.Loaded event and not apply styles to new controls which are added later on.

 

 

Expression Light Theme

ExpressionDarkTheme 

<expressionDark:ExpressionDarkTheme>

    <StackPanel Margin="5">

        <Button Margin="5" Content="Hello Stickperson!"/>

        <ComboBox Margin="5">

            <ComboBoxItem Content="Mr. Stickman" IsSelected="True"/>

        </ComboBox>

        <CheckBox Content="Are you a StickPerson?"/>

        <Slider Margin="5"/>

        <input:NumericUpDown Width="50" Margin="5"/>

    </StackPanel>

</expressionDark:ExpressionDarkTheme>

This is a pretty straight forward sample. We’ve shipped 6 Silverlight Themes with the Silverlight Toolkit.
ExpressionDarkTheme is one of those.

After adding a reference to the correct DLL we can just set our top level container as the Theme Control and all nested controls would get the Expression Dark Theme.

 

ExpressionLightTheme

ExpressionLightTheme

<expressionLight:ExpressionLightTheme>

    <StackPanel Margin="5">

        <Button Margin="5" Content="Hello Stickperson!"/>

        <ComboBox Margin="5">

            <ComboBoxItem Content="Mr. Stickman" IsSelected="True"/>

        </ComboBox>

        <CheckBox Content="Are you a StickPerson?"/>

        <Slider Margin="5"/>

        <input:NumericUpDown Width="50" Margin="5"/>

    </StackPanel>

</expressionLight:ExpressionLightTheme>

 

 

RainierOrangeTheme

RainierOrangeTheme 

<rainerOrange:RainierOrangeTheme>

    <StackPanel Margin="5">

        <Button Margin="5" Content="Hello Stickperson!"/>

        <ComboBox Margin="5">

            <ComboBoxItem Content="Mr. Stickman" IsSelected="True"/>

        </ComboBox>

        <CheckBox Content="Are you a StickPerson?"/>

        <Slider Margin="5"/>

        <input:NumericUpDown Width="50" Margin="5"/>

    </StackPanel>

</rainerOrange:RainierOrangeTheme>

 

 

RainierPurpleTheme

RainierPurpleTheme 

<rainerPurple:RainierPurpleTheme>

    <StackPanel Margin="5">

        <Button Margin="5" Content="Hello Stickperson!"/>

        <ComboBox Margin="5">

            <ComboBoxItem Content="Mr. Stickman" IsSelected="True"/>

        </ComboBox>

        <CheckBox Content="Are you a StickPerson?"/>

        <Slider Margin="5"/>

        <input:NumericUpDown Width="50" Margin="5"/>

    </StackPanel>

</rainerPurple:RainierPurpleTheme>

 

 

ShinyBlueTheme

ShinyBlueTheme 

<shinyBlue:ShinyBlueTheme>

    <StackPanel Margin="5">

        <Button Margin="5" Content="Hello Stickperson!"/>

        <ComboBox Margin="5">

            <ComboBoxItem Content="Mr. Stickman" IsSelected="True"/>

        </ComboBox>

        <CheckBox Content="Are you a StickPerson?"/>

        <Slider Margin="5"/>

        <input:NumericUpDown Width="50" Margin="5"/>

    </StackPanel>

</shinyBlue:ShinyBlueTheme>

 

 

ShinyRedTheme

ShinyRedTheme 

<shinyRed:ShinyRedTheme>

    <StackPanel Margin="5">

        <Button Margin="5" Content="Hello Stickperson!"/>

        <ComboBox Margin="5">

            <ComboBoxItem Content="Mr. Stickman" IsSelected="True"/>

        </ComboBox>

        <CheckBox Content="Are you a StickPerson?"/>

        <Slider Margin="5"/>

        <input:NumericUpDown Width="50" Margin="5"/>

    </StackPanel>

</shinyRed:ShinyRedTheme>

 

 

 

-- Justin Angel

Microsoft Silverlight Program Manager

Published Tuesday, October 28, 2008 6:40 PM by JustinAngel
Filed under:

Comments

# re: Silverlight Toolkit November 2008 Overview

Great!!! This Post is so Good!

Because I am examining one Silverlight Project, development wants to be possible with Toolkit by all means.

#Thanks my Blog's Comment so much  

It was my typo as you said.

Wednesday, October 29, 2008 2:44 AM by naoki

# 2008 October 29 - Links for today &laquo; My (almost) Daily Links

Pingback from  2008 October 29 - Links for today &laquo; My (almost) Daily Links

Wednesday, October 29, 2008 5:44 AM by 2008 October 29 - Links for today « My (almost) Daily Links

# Silverlight Cream for October 29, 2008 - 2 -- #411

In this issue: Justin Angel, Ruurd Boerke, Jeff Wilcox, Pete Brown, and Tim Heuer. This is the 3rd post

Wednesday, October 29, 2008 4:20 PM by Community Blogs

# re: Silverlight Toolkit November 2008 Overview

Hi Justin,

You have put together a number of very, very good Silverlight Toolkit tutorials - your efforts are very helpful and very appreciated.

Thank you,

David Roh

JK@SilverlightAzure.com

Monday, November 17, 2008 8:02 AM by davidjjon77