| Comments

Today at Microsoft PDC, Scott Guthrie demonstrated some of the new controls that have been provided as a part of the Silverlight Toolkit

The Silverlight Toolkit was what was previously named the Silverlight Control Pack in the press release when the runtime was released. 

This toolkit provides a set of controls and themes for Silverlight 2.  In this initial release, they are:

    • AutoCompleteBox
    • Chart
    • DockPanel
    • Label
    • Expander
    • TreeView
    • UpDown
    • ViewBox
    • WrapPanel
    • ImplicitStyleManager
    • Themes (6): ExpressionDark/Light, RanierOrange/Purple, ShinyBlue/Red

These controls are released as an initial version, with tests and available with Ms-Pl licensing on Codeplex.  Of particular interest to me is the Charting components.  Typically available at cost with other platforms, the Silverlight team is providing a base set of Charting controls with source for you to implement, customize and ship with your products.  What is great about this type of control is an implementation with data binding as well, especially with an ObservableCollection.  With this combination you can have a powerful real-time experience updating information without having to re-paint the entire chart or do any postbacks for the app as well.

Let’s take a quick simple sample of what I’m talking about.  To use any of the controls in the toolkit, simply add a reference to the assembly in your project and then use the xmlns declaration at the root of your implementation.  I’m going to use “toolkit” as mine like this:

   1: xmlns:chart="clr-namespace:Microsoft.Windows.Controls.DataVisualization.Charting;assembly=Microsoft.Windows.Controls.DataVisualization"

Then we can use the chart in our XAML along with some other code.  Here I have a Slider and a TextBlock as well showing the value of the Slider as you change it.  I’ve also added the chart series and provided some data binding syntax for the series data:

   1: <UserControl
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     x:Class="SLToolkitDemo.Page"
   5:     xmlns:chart="clr-namespace:Microsoft.Windows.Controls.DataVisualization.Charting;assembly=Microsoft.Windows.Controls.DataVisualization"
   6:     Width="800" Height="600">
   7:     <Grid x:Name="LayoutRoot" Background="White">
   8:         
   9:         <StackPanel Orientation="Vertical" Margin="15">
  10:             <TextBlock Text="Change Line Value"/>
  11:             <Slider x:Name="LineValueSlider" Value="12" Maximum="150" Minimum="0" />
  12:             <TextBlock x:Name="SliderValue" />
  13:             <chart:Chart Height="200" LegendTitle="Item" Title="My Simple Data-bound Chart" 
  14:                          x:Name="MyBarChart">
  15:                 <chart:Chart.Series>
  16:                     <chart:ColumnSeries x:Name="MySalesChartData" Title="Sales of Charts" 
  17:                                         ItemsSource="{Binding}"
  18:                          IndependentValueBinding="{Binding ChartType}"
  19:                          DependentValueBinding="{Binding ChartSaleCount}"/>
  20:                 </chart:Chart.Series>
  21:             </chart:Chart>
  22:             <chart:Chart Height="200" Title="My Simple Pie Chart" x:Name="MyPieChart">
  23:                 <chart:Chart.Series>
  24:                     <chart:PieSeries ItemsSource="{Binding}" 
  25:                                      IndependentValueBinding="{Binding ChartType}"
  26:                                      DependentValueBinding="{Binding ChartSaleCount}" />
  27:                 </chart:Chart.Series>
  28:             </chart:Chart>
  29:         </StackPanel>
  30:         
  31:     </Grid>
  32: </UserControl>

Now in my code I’ve hacked together some simulation of the ObservableCollection changing the value of the Line data to the value of the slider.  Because I implemented my class of Sale with INotifyPropertyChanged the default databinding of OneWay enables my target to be updated once any of my source (salesData) changes.  Here’s the full code:

   1: using System;
   2: using System.Windows;
   3: using System.Windows.Controls;
   4: using System.Windows.Documents;
   5: using System.Windows.Ink;
   6: using System.Windows.Input;
   7: using System.Windows.Media;
   8: using System.Windows.Media.Animation;
   9: using System.Windows.Shapes;
  10: using System.Collections.ObjectModel;
  11: using Microsoft.Windows.Controls.DataVisualization.Charting;
  12:  
  13: namespace SLToolkitDemo
  14: {
  15:     public partial class Page : UserControl
  16:     {
  17:         ObservableCollection<Sale> salesData;
  18:  
  19:         public Page()
  20:         {
  21:             // Required to initialize variables
  22:             InitializeComponent();
  23:             salesData = SalesData.GetData();
  24:             Loaded += new RoutedEventHandler(Page_Loaded);
  25:         }
  26:  
  27:         void Page_Loaded(object sender, RoutedEventArgs e)
  28:         {
  29:             ColumnSeries column = MyBarChart.Series[0] as ColumnSeries;
  30:             PieSeries pie = MyPieChart.Series[0] as PieSeries;
  31:             column.ItemsSource = salesData;
  32:             pie.ItemsSource = salesData;
  33:             LineValueSlider.ValueChanged += new RoutedPropertyChangedEventHandler<double>(LineValueSlider_ValueChanged);
  34:         }
  35:  
  36:         void LineValueSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
  37:         {
  38:             salesData[2].ChartSaleCount = Convert.ToInt32(e.NewValue);
  39:             SliderValue.Text = e.NewValue.ToString();
  40:         }
  41:     }
  42: }

And here is the SalesData.cs class:

   1: using System;
   2: using System.Net;
   3: using System.Windows;
   4: using System.Windows.Controls;
   5: using System.Windows.Documents;
   6: using System.Windows.Ink;
   7: using System.Windows.Input;
   8: using System.Windows.Media;
   9: using System.Windows.Media.Animation;
  10: using System.Windows.Shapes;
  11: using System.Collections.ObjectModel;
  12: using System.Collections.Generic;
  13: using System.ComponentModel;
  14:  
  15: namespace SLToolkitDemo
  16: {
  17:     public class SalesData
  18:     {
  19:         public static ObservableCollection<Sale> GetData()
  20:         {
  21:             ObservableCollection<Sale> sales = new ObservableCollection<Sale>();
  22:             
  23:             sales.Add(new Sale() { ChartSaleCount = 100, ChartType = "Bar" });
  24:             sales.Add(new Sale() { ChartSaleCount = 73, ChartType = "Pie" });
  25:             sales.Add(new Sale() { ChartSaleCount = 12, ChartType = "Line" });
  26:             sales.Add(new Sale() { ChartSaleCount = 24, ChartType = "Spline" });
  27:  
  28:             return sales;
  29:         }
  30:     }
  31:  
  32:     public class Sale : INotifyPropertyChanged
  33:     {
  34:         private int _count;
  35:         public string ChartType { get; set; }
  36:         public int ChartSaleCount
  37:         {
  38:             get { return _count; }
  39:             set
  40:             {
  41:                 _count = value;
  42:                 NotifyPropertyChanged("ChartSaleCount");
  43:             }
  44:         }
  45:  
  46:         #region INotifyPropertyChanged Members
  47:  
  48:         public event PropertyChangedEventHandler PropertyChanged;
  49:  
  50:         public void NotifyPropertyChanged(string propertyName)
  51:         {
  52:             if (PropertyChanged != null)
  53:             {
  54:                 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  55:             }
  56:         }
  57:         #endregion
  58:     }
  59: }

The result of which is when I move the slider to perhaps simulate real-time data, I see the data binding change in the chart represented here:

As you can see I have two charts using the same ObservableCollection<T>, so changing the data, changes both of the charts without any extra effort. 

Charting along with some of the other controls brings this really, really nice addition to Silverlight 2.  I hope you find them valuable.  We’ll be using them in projects and digging deeper (especially in charting) on the Silverlight Community Site, so I hope you visit there.  You can download the actual sample project for this file as well right here: SLToolkitDemo.zip

If you liked this post, please consider subscribing to the feed for more like it.  Justin Angel is also a program manager for the toolkit that you should check out some depth posts from him on the controls as well.  You can visit the samples site here showing you a gallery of the controls in implementation.

| Comments

In the early days of Silverlight 2, one of the included controls was the WatermarkedTextBox.  In Beta 2 the control was removed from the runtime for among other things, WPF compatibility.  The control source code was made available for people to look at as it was referenced in a few projects, namely ScottGu’s Digg sample application.  There was hinting about future plans but nothing concrete. 

Now that Silverlight 2 is released, the control is not there :-).  I’ve gotten enough requests about it that I wanted to provide some action for you.  First, let me say that there are no concrete plans for WatermarkedTextBox at this time that I have to share.  I’m not saying there isn’t plans, but just that none at a point to make any worthwhile announcements.  Perhaps something like this would show up in the Silverlight Toolkit, but at this time no plans have been defined.

Again, as I’ve received enough requests, I’ve modified the source code for WatermarkedTextBox for Silverlight 2 release and am making it available for you to consume.  The code has been updated for use in Silverlight 2 and also updated to reflect the default styling of the released controls (namely to match TextBox).

If you aren’t familiar with the concept, it’s basically a TextBox with a value you can set for some helper text if the value is not set.  Typically you use this when you want to provide “prompt” text for some input, as an example here:

As you can see the TextBox provides a '”faded” default text that isn’t the TextBox.Text property of the control, but rather the Watermark property of this control.  Once data is entered in the control, the watermark goes away.  As long as data is input the watermark isn’t displayed…if the value is empty, the watermark displays.  Simple enough.

The XAML for the above looks like this:

   1: <UserControl x:Class="WatermarkTester.Page"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:local="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls.WatermarkedTextBox"
   5:     Height="300" Width="600" xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">
   6:     <Grid x:Name="LayoutRoot" Background="White">
   7:         <StackPanel Orientation="Vertical">
   8:             <Grid Margin="15">
   9:                 <Grid.RowDefinitions>
  10:                     <RowDefinition Height="Auto" />
  11:                     <RowDefinition Height="Auto" />
  12:                     <RowDefinition Height="Auto" />
  13:                     <RowDefinition Height="Auto" />
  14:                 </Grid.RowDefinitions>
  15:                 <Grid.ColumnDefinitions>
  16:                     <ColumnDefinition Width="Auto" />
  17:                     <ColumnDefinition Width="Auto" />
  18:                 </Grid.ColumnDefinitions>
  19:                 <TextBlock Text="First Name:" Margin="5" Grid.Column="0" Grid.Row="0" />
  20:                 <local:WatermarkedTextBox Grid.Column="1" Grid.Row="0" Watermark="Enter your first name here..."/>
  21:                 <TextBlock Text="Last Name:" Margin="5" Grid.Column="0" Grid.Row="1" />
  22:                 <local:WatermarkedTextBox Grid.Column="1" Grid.Row="1" Watermark="Enter your last name here..." />
  23:                 <TextBlock Text="Phone Number:" Margin="5" Grid.Column="0" Grid.Row="2" />
  24:                 <local:WatermarkedTextBox Grid.Column="1" Grid.Row="2" Watermark="(xxx) xxx-xxxx" />
  25:             </Grid>
  26:         </StackPanel>
  27:     </Grid>
  28: </UserControl>

Note the xmlns:local declaration in the user control which references the binary.

The control is also Blend compatible if you want to change the style/control template so if you wanted to change the Watermark color or something like that you could easily do that with Blend:

So if you’ve been looking for this control, here you go.  You can download the bits here:

The source is available as Ms-Pl.  Hope this helps!

| Comments

Last week I had the pleasure of talking with the crew from the Herding Code podcast.  Among the questions was one about the open source community and Silverlight.  There was mention about MVCContrib and how that community sprouted almost instantly with the ASP.NET MVC initial releases.  I let the Herding Code crew know that I believe there already is a vibrant open source community around Silverlight and pointed to things like DevExpress’ AgDataGrid control which is free and provides source.  I also mentioned a project that did start right away around Silverlight 2 initial releases: .  The project, started by Page Brooks, had a good start and keeps on rolling now as they just released a set of free open source Silverlight controls!

The team of Page Brooks, Rob Houweling, Koen Zwikstra, and Shawn Wildermuth have just released “Alpha 2” of the project which includes:

    • Color Picker
    • Gauge Control
    • Star Selector
    • Enhanced Metafile (EMF)
    • Cool Menu
    • Libraries: Zip, Byte utilities, String utilities, Simple text parser, Animation Tweening, Wheel Mouse listener

While the project code is hosted at Codeplex, the team also has a blog at SilverlightContrib.org which has a Live Demo page that will show you demonstrations about the controls:

Color Picker:

Cool Menu (OSX style):

Gauge samples:

The code is available with the Ms-Pl license which is very permissive, so go and grab these controls…and better yet…contribute back to the project!!!  There are more than just controls there as I mentioned there are libraries as well – check out the Live Demo for examples.  I haven’t checked to see their compatibility with the Blend designer, but that is something you can tweak with yourself as needed.

Congratulations to Page and the team for a great community resource and a great release.  I look forward to more great things!

| Comments

Are you using SharePoint and want to know how to leverage Silverlight?  Have you seen the Blueprints project on Codeplex?  But what if those particular implementations don’t meet your needs and you want to create your own contained web part with your Silverlight 2 application?

Kirk Evans writes about a method of doing this in a recent post: Hosting Silverlight in SharePoint.  Take a look at Kirk’s post with a step-by-step guide of getting started with his method.  In looking at the method he describes, it is conceivable that you actually could make a more generic web part that serves as a XAP host and allows the user to set the property of the Source to a URI for a Silverlight 2 application.

Hmmm…I wonder if Kirk is up to modifying it ;-).

UPDATE (08 OCT 2008):

Looks like there is a similiar web part in the works already!  Thanks to a note from Andy Nogueira, he has a project (also on Codeplex) for SilverPart, which is a Silverlight wrapper web part for SharePoint.  Thanks for the pointer Andy!

| Comments

One of the things that I’ve wanted to do since Silverlight released was two things with text, enable a Stroke and layout text on a Path.  Both of which in Silverlight 2 aren’t readily available.  Luckily we have a great ecosystem of developers and MVPs who love to extend our frameworks and create new capabilities for developers.

Bill Reiss has done just that.  You may recognize Bill from some XNA and Silverlight gaming fame.  His game of Dr. Popper still remains my daughter’s favorite computer game!  Bill has created a new Silverlight user control he calls PathTextBlock control.  Bill describes the new control:

“The PathTextBlock control converts text to a Path which allows you to do a couple of things you can't normally do with text in Silverlight. First of all, instead of a Foreground brush, you have a Stroke and a Fill, which allows you to draw text with an outline. Secondly, the PathTextBlock supports Transform objects which can allow you to distort the text, draw it along a curve, or other transforms. You can easily create your own transforms as well.”

This basically allows you to have a normal TextBlock, but distort and outline it…here’s an example output:

Bill has also included a few transforms to play around with as well.  All of this is included in an Ms-Pl licensed component that is available on Codeplex.  Go check out Bill’s blog post for a link and description.