Monday, April 4, 2011

In my current development project, my MVVM pivot app needed to create a pie chart from a collection of objects. I read David Anson’s (@DavidAns) blog about using Charts in Windows Phone 7 (WP7) development. His example uses a detailed Resource Dictionary for the style of the chart. I’m so new to Silverlight that the XAML markup of David’s example tripped me up. This blog post is for other newbies trying to rework static resources into dynamic binding.

In Silverlight, static resources are those that are already defined, hence static. This is great for a known set or for working in the Visual Studio Design-time environment. Dynamic resources can only be viewed in the runtime environment where they can also be changed.

A chart is a parent with child nodes of legend and pieseries. Since the Chart is a parent with several children, I wasn’t sure where to bind my collection of dynamic objects which would determine the percentage of the pie slices. I also needed to move the code strictly not associated with the chart to a different file/class. The example below is similar to the real life problem I was trying to solve. The code is taken from David’s example.

Method 1: {StaticResource}

First it is helpful to explain the markup in David’s example that I didn’t understand. His example places the following data object in the code-behind for the page but outside the page class:

In the <PieSeries> object, the ItemsSource attribute is tied to a static resource of Activities because it has been defined in the <phone.PhoneApplicationPage.Resources> object noted just above. A Pie Chart requires two data points, name and value, to draw the pie. These are Activity and Count in the ActivityInfo class. They are bound from the class to the PieChart via the DependentValuePath and the IndependentValuePath. David’s complete <Chart> object looks like:

To be credit, his example works and is a great way of connecting code to an object via the StaticResource keyword. The nice thing about his method is that the PieChart displays in Visual Studio design time.

Because I wanted the XAML and code-behind to follow the pattern of the app I had in progress, David’s approach wouldn’t work for me. My code was not all in the code-behind but spread across the model classes for better organization and maintenance. I needed to figure out how to switch the binding from:

ItemsSource="{StaticResource Activities}"toItemsSource="{Binding}"

Method 2: {Binding}

Here is what I had to do to make this simple binding work:

moved the Activity and ActivityInfo classes into their own class/file but same namespace and removed the Resource XAML above the Grid.

Bind via code, not to the PieSeries but instead to the parent Chart, add this line of code after the MainPage Constructor’s InitializeComponent() call.

myChart.DataContext = new Activities();

This last step, #4, I hooked my data object, Activities, to the XAML object Chart. The good thing about this is that the exact data is connected to the exact object. The bad thing is that if I want to add more objects or different data elements to this page, this code is too restrictive. A better consideration for maintence would be to tie my App-level data model object to the page-level DataContext in the MainPage Constructor’s InitializeComponent() call: