(转)Silverlight–Displaying Tookit Charts from XML Data

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>  
<?xml version="1.0" encoding="utf-8" ?>
<dataSets>
  <dataSet title="Two Times Table">
    <data x="1"
          y="2"/>
    <data x="2"
          y="4"/>
    <data x="3"
          y="6"/>
    <data x="4"
          y="8"/>
    <data x="5"
          y="10"/>
  </dataSet>
  <dataSet title="Three Times Table">
    <data x="1"
          y="3"/>
    <data x="2"
          y="6"/>

  <!-- you get the idea, it goes up to 5 times table -->

</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>  
<UserControl
  x:Class="XmlTestApp.MainPage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:local="clr-namespace:XmlTestApp"
  mc:Ignorable="d"
  d:DesignHeight="300"
  d:DesignWidth="400"
  xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">

  <!-- My kingdom for a markup extension :-) -->
  <UserControl.Resources>
    <local:XmlDataSource
      x:Key="dataSource"
      DownloadUri="data.xml" />
  </UserControl.Resources>

  <Grid
    x:Name="LayoutRoot"
    Background="White">
    <Grid.ColumnDefinitions>
      <ColumnDefinition />
      <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <ListBox
      DataContext="{StaticResource dataSource}"
      ItemsSource="{Binding Path=Xml.[descendant-or-self::dataSet]}">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <Border
            BorderBrush="Black"
            CornerRadius="2"
            Margin="3"
            Padding="3">
            <Grid>
              <Grid.RowDefinitions>
                <RowDefinition
                  Height="Auto" />
                <RowDefinition
                  MaxHeight="144" />
              </Grid.RowDefinitions>
              <TextBlock
                Margin="3"
                HorizontalAlignment="Center"
                Text="{Binding Path=[string(attribute::title)]}" />
              <toolkit:Chart                
                Grid.Row="1"
                Margin="3"
                HorizontalAlignment="Center"
                Title="{Binding Path=[string(attribute::title)]}">
                <toolkit:Chart.Series>
                  <toolkit:LineSeries
                    Title="{Binding Path=[string(attribute::title)]}"
                    ItemsSource="{Binding Path=[child::data]}"
                    DependentValueBinding="{Binding Path=[number(attribute::y)]}"
                    IndependentValueBinding="{Binding Path=[number(attribute::x)]}" />
                </toolkit:Chart.Series>
              </toolkit:Chart>
            </Grid>
          </Border>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
    <local:MultiChart
      Grid.Column="1"
      DataContext="{StaticResource dataSource}"
      SeriesSource="{Binding Path=Xml.[descendant-or-self::dataSet]}">      
      <local:MultiChart.SeriesTemplate>
        <DataTemplate>
          <toolkit:LineSeries
            Title="{Binding Path=[string(attribute::title)]}"
            ItemsSource="{Binding Path=[child::data]}"
            DependentValueBinding="{Binding Path=[number(attribute::y)]}"
            IndependentValueBinding="{Binding Path=[number(attribute::x)]}" />
        </DataTemplate>
      </local:MultiChart.SeriesTemplate>
    </local:MultiChart>
  </Grid>
</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.

转载于:https://www.cnblogs.com/allanli/archive/2011/01/10/1931710.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值