I am working on a Silverlight project, where we doing straight MVVM. Binding the Chart control included in the Silverlight Toolkit (www.codeplex.com/Silverlight) to a ViewModel is quite simple. But what when I want to bind a collection of different “graphs” each with an own collection of data-points to a single chart?
Suppose a line-chart with dynamically changing the numbers of lines.
I decided to use a DataTemplate similar to the ItemsTemplate in the ItemsControl class.
So, I created the MultiChart control as sub class of the Silverlight Toolkit Chart control.
public class MutliChart : System.Windows.Controls.DataVisualization.Charting.Chart { }
Then I added two dependency properties (full source code is attached)
public IEnumerable SeriesSource { get { return (IEnumerable)GetValue(SeriesSourceProperty); } set { SetValue(SeriesSourceProperty, value); } } public DataTemplate SeriesTemplate { get { return (DataTemplate)GetValue(SeriesTemplateProperty); } set { SetValue(SeriesTemplateProperty, value); } }
Now, I’m able to databind my multi-series datasource to the SeriesSource property similar as one binds the ItemsSource to an ItemsControl or a DataGrid control. The MultiChart control generates DataSeries items based on the SeriesTemplate. The series are now full bindable to a dynamic list in the ViewModel.
The XAML locks like this:
<local:MultiChart SeriesSource="{Binding MySalesData}" > <local:MultiChart.SeriesTemplate > <DataTemplate > <chartingToolkit:LineSeries Title="{Binding Title}" ItemsSource="{Binding Sales}" IndependentValueBinding="{Binding SalesName}" DependentValueBinding="{Binding SalesTotal}" /> </DataTemplate> </local:MultiChart.SeriesTemplate> </local:MultiChart>
This implementation is similar to the content model in other controls i.e., Content and ContentTemplate, Header and HeaderTemplate, Items or ItemsSource and ItemTemplate, etc.
But what if I want to have different chart-series in the same chart such as column-series and line-series databound to the ViewModel?
What I need is a different DataTemplate per item type in the data source. Unfortunately Silverlight does not support typed data-templates natively. WPF answers this problem with DataTemplateSelector (and the ContentTemplateSelector, HeaderTemplateSelector, and ItemTemplateSelector properties). Silverlight doesn’t yet support it, but we can achieve the same effect after a little more code.
So, I added another dependency property called SeriesTemplateSelector.
public DataTemplateSelector SeriesTemplateSelector { get { return (DataTemplateSelector)GetValue(SeriesTemplateSelectorProperty); } set { SetValue(SeriesTemplateSelectorProperty, value); } }
The class DataTemplateSelector does not exists in Silverlight. So, I just copied the DataTemplateSelector base class from the WPF assembly (via Reflector).
// code from WPF using System; using System.Windows; namespace System.Windows.Controls { // Summary: // Provides a way to choose a System.Windows.DataTemplate based on the data // object and the data-bound element. public class DataTemplateSelector { // Summary: // Initializes a new instance of the System.Windows.Controls.DataTemplateSelector // class. public DataTemplateSelector() { } // Summary: // When overridden in a derived class, returns a System.Windows.DataTemplate // based on custom logic. // // Parameters: // item: // The data object for which to select the template. // // container: // The data-bound object. // // Returns: // Returns a System.Windows.DataTemplate or null. The default value is null. public virtual DataTemplate SelectTemplate(object item, DependencyObject container) { return null; } } }
If the SeriesTemplateSelector is set then the MultiChart control selects its data-template with this instance.
At the end my XAML looks like this:
<UserControl> <UserControl.Resources > <local:SeriesTemplateSelector x:Key="chartTemplateSelector"> <local:SeriesTemplateSelector.SalesTemplate> <DataTemplate > <chartingToolkit:LineSeries Title="{Binding SalesName}" ItemsSource="{Binding SalesTotals}" IndependentValueBinding="{Binding Date}" DependentValueBinding="{Binding SalesTotal}" /> </DataTemplate> </local:SeriesTemplateSelector.SalesTemplate> <local:SeriesTemplateSelector.MedianTemplate> <DataTemplate > <chartingToolkit:ColumnSeries Title="{Binding SalesName}" ItemsSource="{Binding SalesTotals}" IndependentValueBinding="{Binding Date}" DependentValueBinding="{Binding SalesTotal}" /> </DataTemplate> </local:SeriesTemplateSelector.MedianTemplate> </local:SeriesTemplateSelector> </UserControl.Resources> <Grid x:Name="LayoutRoot"> <local:MultiChart SeriesSource="{Binding SalesDataWithMedian}" SeriesTemplateSelector="{StaticResource chartTemplateSelector}" Title="Dynamic Multi Lines with different DataTemplates"> </local:MultiChart> </Grid> </UserControl>
Here the implementation of SeriesTemplateSelector class:
public class SeriesTemplateSelector : DataTemplateSelector { public DataTemplate SalesTemplate { get; set; } public DataTemplate MedianTemplate { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { if (item is SalesPerformance) { SalesPerformance salesPerf = item as SalesPerformance; if (salesPerf.SalesName == "Median") { return MedianTemplate; } else { return SalesTemplate; } } // default return null; } }
Finally I got a fully bindable mutli-series chart control which provides the same content model as other well-known control such the ItemsControl.

[...] behavior with native UIElement MouseWheel eventMemory leak with focusable UIElement in Silverlight?Databinding Multi-Series ChartsBe careful when using WeakReference.IsAliveBasicHttpBinaryBinding for [...]
By: How to make Visifire Chart bindable to ViewModel « Kiener's Blog on February 22, 2010
at 11:05 am
how do you inherit from a sealed class?
i download the demo project and visual studio is telling me that, “MultiChart: cannot derive from a sealed class System.Windows.Controls.DataVisualization.Charting.Chart”.
can you help me with this ?
By: enio on March 10, 2010
at 2:39 pm
Hi,
the Silverlight Toolkit Team unsealed them in the October 2009 Release.
Check complete change list here: http://go.microsoft.com/fwlink/?LinkId=165469
Please download and use the latest Silverlight Toolkit from http://www.codeplex.com/Silverlight
Best regards,
Beat
By: beatkiener on March 10, 2010
at 2:53 pm
yeah, now this is working, in the changes of the last version says:
“Supports more flexible subclassing scenarios of core classes”
this solves my problem to derive the MultiChart from the Chart class,
but, what if i want use it in a WPF Application, and not in silverlight application?
is been quite a mess, because a need to get the WPFToolkit, and i am very confusing with the correct versions of the System.Windows.Controls.DataVisualization.Toolkit that i need to have to run it in a WPF Application.
By: enio on March 10, 2010
at 5:16 pm