现在的位置: 首页 > 综合 > 正文

(转)Silverlight–Displaying Tookit Charts from XML Data

2012年09月01日 ⁄ 综合 ⁄ 共 7999字 ⁄ 字号 评论关闭

Silverlight–Displaying Tookit Charts from XML Data

Every now and again I revisit my obsession with data-binding to XML data and Silverlight and this is one of those posts.

Now, to be fair, this was prompted by chatting to Rich who pointed me at one of my old blog posts about binding to XML data;

“Silverlight and XML Binding”

which I fully accept has a bunch of limitations but does (via a hacky use of being able to bind to string indexers) get you some way towards binding to XML.

In that blog post, I wrote two classes – BindableXNode and XmlDataSource and I’ll repeat neither of them here.

Our chat was about binding from XML data onto a Silverlight Toolkit charting control and, specifically, binding multiple datasets onto a single chart from that XML.

Now, I don’t think that a Silverlight Toolkit chart control has a facility to bind to multiple sources of chart data at a time and so I borrowed a simplified version of a MultiChart control from this excellent blog post by Beat which adds a SeriesSource property to the ChartControl ( it also does a little more that I didn’t need so I removed those bits for simplicity ).

Then I wrote a little XML file of test data;

  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <dataSets>  
  3.   <dataSet title="Two Times Table">  
  4.     <data x="1"  
  5.           y="2"/>  
  6.     <data x="2"  
  7.           y="4"/>  
  8.     <data x="3"  
  9.           y="6"/>  
  10.     <data x="4"  
  11.           y="8"/>  
  12.     <data x="5"  
  13.           y="10"/>  
  14.   </dataSet>  
  15.   <dataSet title="Three Times Table">  
  16.     <data x="1"  
  17.           y="3"/>  
  18.     <data x="2"  
  19.           y="6"/>  
  20.   
  21.   <!-- you get the idea, it goes up to 5 times table -->  
  22.   
  23. </dataSets>  

and I dropped this into my ClientBin folder on my web site within a new Silverlight project;

image

Now, time to read it and bind it onto the screen. Here’s the simple UI I ended up with;

image

In the left hand column is a ListBox which is displaying the 5 charts separately whilst in the right hand column is a MultiChart displaying all the lines on a single chart.

Here’s the XAML I ended up with (there’s no code in this blog post, it’s a XAML-only zone Smile);

 

  1. <UserControl  
  2.   x:Class="XmlTestApp.MainPage"  
  3.   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  4.   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  5.   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  6.   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
  7.   xmlns:local="clr-namespace:XmlTestApp"  
  8.   mc:Ignorable="d"  
  9.   d:DesignHeight="300"  
  10.   d:DesignWidth="400"  
  11.   xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">  
  12.   
  13.   <!-- My kingdom for a markup extension :-) -->  
  14.   <UserControl.Resources>  
  15.     <local:XmlDataSource  
  16.       x:Key="dataSource"  
  17.       DownloadUri="data.xml" />  
  18.   </UserControl.Resources>  
  19.   
  20.   <Grid  
  21.     x:Name="LayoutRoot"  
  22.     Background="White">  
  23.     <Grid.ColumnDefinitions>  
  24.       <ColumnDefinition />  
  25.       <ColumnDefinition />  
  26.     </Grid.ColumnDefinitions>  
  27.     <ListBox  
  28.       DataContext="{StaticResource dataSource}"  
  29.       ItemsSource="{Binding Path=Xml.[descendant-or-self::dataSet]}">  
  30.       <ListBox.ItemTemplate>  
  31.         <DataTemplate>  
  32.           <Border  
  33.             BorderBrush="Black"  
  34.             CornerRadius="2"  
  35.             Margin="3"  
  36.             Padding="3">  
  37.             <Grid>  
  38.               <Grid.RowDefinitions>  
  39.                 <RowDefinition  
  40.                   Height="Auto" />  
  41.                 <RowDefinition  
  42.                   MaxHeight="144" />  
  43.               </Grid.RowDefinitions>  
  44.               <TextBlock  
  45.                 Margin="3"  
  46.                 HorizontalAlignment="Center"  
  47.                 Text="{Binding Path=[string(attribute::title)]}" />  
  48.               <toolkit:Chart                  
  49.                 Grid.Row="1"  
  50.                 Margin="3"  
  51.                 HorizontalAlignment="Center"  
  52.                 Title="{Binding Path=[string(attribute::title)]}">  
  53.                 <toolkit:Chart.Series>  
  54.                   <toolkit:LineSeries  
  55.                     Title="{Binding Path=[string(attribute::title)]}"  
  56.                     ItemsSource="{Binding Path=[child::data]}"  
  57.                     DependentValueBinding="{Binding Path=[number(attribute::y)]}"  
  58.                     IndependentValueBinding="{Binding Path=[number(attribute::x)]}" />  
  59.                 </toolkit:Chart.Series>  
  60.               </toolkit:Chart>  
  61.             </Grid>  
  62.           </Border>  
  63.         </DataTemplate>  
  64.       </ListBox.ItemTemplate>  
  65.     </ListBox>  
  66.     <local:MultiChart  
  67.       Grid.Column="1"  
  68.       DataContext="{StaticResource dataSource}"  
  69.       SeriesSource="{Binding Path=Xml.[descendant-or-self::dataSet]}">        
  70.       <local:MultiChart.SeriesTemplate>  
  71.         <DataTemplate>  
  72.           <toolkit:LineSeries  
  73.             Title="{Binding Path=[string(attribute::title)]}"  
  74.             ItemsSource="{Binding Path=[child::data]}"  
  75.             DependentValueBinding="{Binding Path=[number(attribute::y)]}"  
  76.             IndependentValueBinding="{Binding Path=[number(attribute::x)]}" />  
  77.         </DataTemplate>  
  78.       </local:MultiChart.SeriesTemplate>  
  79.     </local:MultiChart>  
  80.   </Grid>  
  81. </UserControl>  

and so this is using my XmlDataSource class to asynchronously download data.xml. It then sets up a bunch of bindings;

  • ListBox – ItemsSource = dataSet elements
    • TextBlock – Text = title attribute
    • Chart
      • LineSeries
        • Title = title attribute
        • ItemsSource = data child elements
        • DependentValueBinding = y attribute
        • IndependentValueBinding = x attribute
  • MultiChart – SeriesSource = dataSet elements
    • SeriesTemplate
      • LineSeries (bound up as before & duplicated here)

and that’s pretty much it. Async download of XML and charts onto the screen with no “code” to write but a lot of XAML to play around with.

Here’s the project for download.

Please note this includes a source file that is not mine (MultiChart.cs) and I’ve clearly marked it that way. You should contact the original author around use of his work.

抱歉!评论已关闭.