65.9K
CodeProject 正在变化。 阅读更多。
Home

Silverlight 4 Toolkit 中图表控件的样式

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (13投票s)

2011年8月22日

CPOL

3分钟阅读

viewsIcon

65733

downloadIcon

2476

通过设置 Silverlight Toolkit 中的图表控件样式,创造新的外观和感觉。

引言

我注意到许多人,包括我自己,在 styling Silverlight 4 Toolkit 中附带的 Chart 控件时遇到了一些困难。要深入到控件的视觉树以在 Expression Blend 的 Design 视图中 styling 该控件,以获得良好的外观和感觉,相对来说是比较困难的。我在网上搜索了一下,关于如何进行此过程的信息很少,于是我决定自己来解决。我成功地重新 styling 了图表控件,并且大部分工作都是在 XAML 中完成的。我认为本文将缓解其他开发者/设计师在面临同样问题时的挑战。

Silverlight 4 Toolkit 中包含一系列 Chart 控件,其中一些列在下面

  • BarSeries
  • ColumnSeries
  • StackedColumnSeries
  • BubbleSeries
  • LineSeries
  • PieSeries
  • ScatterSeries

我将讨论其中的两个系列

  • ColumnSeries
  • StackedColumnSeries

注意:您可以在 Expression Blend 4 和 Visual Studio 2010 中遵循本文中的步骤,但我将在本文中使用 Expression Blend 4。如果您没有该工具包,可以在 Silverlight Toolkit - CodePlex 下载。

ColumnSeries

在创建了一个新的 Silverlight 应用程序后,我添加了一个 Chart 控件并编辑了 Template。在本文中,我决定从 Template 中删除 Legend 和 Chart Title,因为我不需要它们。Chart Title 仍然可以使用,所以您可以保留您的,但 Legend 没有用,因为我们将为每个柱子使用不同的颜色。图表控件现在看起来像这样

Chart1.png

接下来,编辑 XAML 以将 Chart 控件的 DependentValueBindingIndependentValueBinding 属性绑定到一个控制每个柱子的类。DataPointStyle 属性也绑定到一个用于控制柱子外观的样式。XAML 如下

<toolkit:Chart x:Name="GasChart" Style="{StaticResource GasChartStyle}" 
    BorderBrush="{x:Null}" Margin="4,141,0,60">
    <toolkit:ColumnSeries 
    DependentValueBinding="{Binding GasValue}" 
    IndependentValueBinding="{Binding GasName}" 
    DataPointStyle="{StaticResource ColorByGradeColumn}" 
    AnimationSequence="FirstToLast"/>
</toolkit:Chart>

DataPointStyle 设置为 StaticResource,它为 ColumnDataPoint 设置了 ControlTemplate。此时,我们正在改变柱子的外观。这种外观是一个类似光泽的柱子,与默认的难看外观相比。仔细查看下面的 XAML 代码,您会注意到 ControlTemplateBorderBackground 属性绑定到了一个类的一个属性 (GasColor)。这使得可以动态更改柱子的颜色

<Style x:Key="ColorByGradeColumn" TargetType="toolkit:ColumnDataPoint">
    <Setter Property="Background" Value="DarkGray"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="toolkit:ColumnDataPoint">
                <Border  Background="{Binding GasColor}" 
                         BorderBrush="{Binding GasColor}" 
                         BorderThickness="0.5">
                    <Grid Background="{x:Null}">
                        <ToolTipService.ToolTip>
                        <!--Provides the tooltip for each column -->
                            <StackPanel>
                                <ContentControl 
                                  Content ="{ TemplateBinding IndependentValue }"/>
                                <StackPanel Orientation="Horizontal">
                                      <ContentControl 
                                        Content ="{ TemplateBinding 
                                             FormattedDependentValue }"/>
                                    <ContentControl Content ="ppm"/>
                                </StackPanel>
                            </StackPanel>
                        </ToolTipService.ToolTip>
                        <Border BorderBrush="{x:Null}">
                            <Border.Background>
                                <!--This gradiesnt provides 
                                           the gloss-like feature for each-->
                                <LinearGradientBrush EndPoint="1.344,0.5" 
                                          StartPoint="-0.344,0.5">
                                    <GradientStop Color="White" Offset="0"/>
                                    <GradientStop Color="{Binding GasColor}" 
                                          Offset="0.5"/>
                                </LinearGradientBrush>
                            </Border.Background>
                        </Border>
                    </Grid>
                </Border>            
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

现在,属性绑定到 Chart 控件的类是

public class GasNameValue
{
    public double GasValue { get; set; }
    public string GasName { get; set; }
    public Brush GasColor { get; set; }
}

下面的方法在一个 List 中创建上面类的新对象,其中设置了每个柱子的值。创建的对象数量将决定您的 Chart 将包含多少个柱子;大多数情况下,您的数据来自数据库或云,这个过程将是动态的而不是手动的。最后一行代码将 Chart 控件的 ItemsSource 设置为 List 对象。

private void SetData()
{
    List<GasNameValue> gasList = new List<GasNameValue>
    {
        new GasNameValue
        {
            GasName = "CO2",
            GasValue = 850.0,
            GasColor = new SolidColorBrush(Colors.Red)
        },
        new GasNameValue
        {
            GasName = "SO2",
            GasValue = 700.0,
            GasColor = new SolidColorBrush(Colors.Blue)
        },
        new GasNameValue
        {
            GasName = "CH4",
            GasValue = 820.0,
            GasColor = new SolidColorBrush(Colors.Green)
        },
        new GasNameValue
        {
            GasName = "NO2",
            GasValue = 600.0,
            GasColor = new SolidColorBrush(Colors.Yellow)
        },
        new GasName_Value
        {
            GasName = "F11",
            GasValue = 910.o,
            GasColor = new SolidColorBrush(Colors.Purple)
        },
        new GasNameValue
        {
            GasName = "F12",
            GasValue = 760.0,
            GasColor = new SolidColorBrush(Colors.Orange)
        },
    };
    ((ColumnSeries)GasChart.Series[0]).ItemsSource = gasList;
}

最终的 ColumnSeries 看起来像这样

Chart2.png

StackedColumnSeries

默认的 StackedColumnSeries 看起来像这样(在我看来很难看)

Chart4.png

现在,在处理 StackedColumnSeries 时,在添加 Chart 控件并相应地编辑 Template 后,您需要为每个Stacked Column 添加 SeriesDefinition。您添加的 SeriesDefinition 的数量决定了每个 Stacked Column 上您最终拥有的分区数量。下面的 XAML 在每个 Stacked Column 上包含六 (6) 个分区,并且属性绑定到一个类

<toolkit:StackedColumnSeries>
    <toolkit:SeriesDefinition
        Title="CO2"
        ItemsSource="{Binding}"
        DependentValueBinding="{Binding GasValue1}" 
        IndependentValueBinding="{Binding Year}"/>
    <toolkit:SeriesDefinition
        Title="SO2"
        ItemsSource="{Binding}"
        DependentValueBinding="{Binding GasValue2}" 
        IndependentValueBinding="{Binding Year}"/>
    <toolkit:SeriesDefinition
        Title="NO2"
        ItemsSource="{Binding}"
        DependentValueBinding="{Binding GasValue3}" 
        IndependentValueBinding="{Binding Year}"/>
        <toolkit:SeriesDefinition
        Title="CH4"
        ItemsSource="{Binding}"
        DependentValueBinding="{Binding GasValue4}" 
        IndependentValueBinding="{Binding Year}"/>
    <toolkit:SeriesDefinition
        Title="F11"
        ItemsSource="{Binding}"
        DependentValueBinding="{Binding GasValue5}" 
        IndependentValueBinding="{Binding Year}"/>
    <toolkit:SeriesDefinition
        Title="F12"
        ItemsSource="{Binding}"
        DependentValueBinding="{Binding GasValue6}" 
        IndependentValueBinding="{Binding Year}"/>
</toolkit:StackedColumnSeries>

这一次,为了创建每个分区的新颜色,必须将 ResourceDictionaryCollection 添加到图表调色板中;这个 ResourceDictionaryCollection 包含六 (6) 个 ResourceDictionary。每个 ResourceDictionary 为堆栈上的每个分区提供颜色。XAML 如下

<toolkit:Chart.Palette>
    <toolkit:ResourceDictionaryCollection>
        <ResourceDictionary>
            <Style x:Key="DataPointStyle" TargetType="toolkit:ColumnDataPoint">
                <Setter Property="Background" Value="Red"/>
                <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="toolkit:ColumnDataPoint">
                        <Border Background="Red" BorderBrush="Red" BorderThickness="0.5">
                            <Grid Background="{x:Null}">
                                <ToolTipService.ToolTip>
                                        <StackPanel Orientation="Horizontal">
                                              <ContentControl 
                                              Content ="{ TemplateBinding 
                                                 FormattedDependentValue }"/>
                                            <ContentControl Content =" ppm"/>
                                        </StackPanel>
                                </ToolTipService.ToolTip>
                                <Border BorderBrush="{x:Null}">
                                    <Border.Background>
                                        <LinearGradientBrush EndPoint="1.344,0.5" 
                                            StartPoint="-0.344,0.5">
                                            <GradientStop Color="White" Offset="0"/>
                                            <GradientStop Color="Red" Offset="0.5"/>
                                        </LinearGradientBrush>
                                    </Border.Background>
                                </Border>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            </Style>
        </ResourceDictionary>
        <ResourceDictionary>
            <Style x:Key="DataPointStyle" TargetType="Control">
                <Setter Property="Background" Value="Blue"/>
                <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="toolkit:ColumnDataPoint">
                        <Border Background="Blue" 
                              BorderBrush="Blue" BorderThickness="0.5">
                            <Grid Background="{x:Null}">
                                <ToolTipService.ToolTip>
                                        <StackPanel Orientation="Horizontal">
                                              <ContentControl 
                                              Content ="{ TemplateBinding 
                                                  FormattedDependentValue }"/>
                                            <ContentControl Content =" ppm"/>
                                        </StackPanel>
                                </ToolTipService.ToolTip>
                                <Border BorderBrush="{x:Null}">
                                    <Border.Background>
                                        <LinearGradientBrush EndPoint="1.344,0.5" 
                                            StartPoint="-0.344,0.5">
                                            <GradientStop Color="White" Offset="0"/>
                                            <GradientStop Color="Blue" Offset="0.5"/>
                                        </LinearGradientBrush>
                                    </Border.Background>
                                </Border>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            </Style>
        </ResourceDictionary>
        <ResourceDictionary>
            <Style x:Key="DataPointStyle" TargetType="Control">
                <Setter Property="Background" Value="Green"/>
                <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="toolkit:ColumnDataPoint">
                        <Border Background="Green" 
                               BorderBrush="Green" BorderThickness="0.5">
                            <Grid Background="{x:Null}">
                                <ToolTipService.ToolTip>
                                        <StackPanel Orientation="Horizontal">
                                              <ContentControl 
                                              Content ="{ TemplateBinding 
                                                   FormattedDependentValue }"/>
                                            <ContentControl Content =" ppm"/>
                                        </StackPanel>
                                </ToolTipService.ToolTip>
                                <Border BorderBrush="{x:Null}">
                                    <Border.Background>
                                        <LinearGradientBrush EndPoint="1.344,0.5" 
                                        StartPoint="-0.344,0.5">
                                            <GradientStop Color="White" Offset="0"/>
                                            <GradientStop Color="Green" Offset="0.5"/>
                                        </LinearGradientBrush>
                                    </Border.Background>
                                </Border>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            </Style>
        </ResourceDictionary><ResourceDictionary>
            <Style x:Key="DataPointStyle" TargetType="Control">
                <Setter Property="Background" Value="Yellow"/>
                <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="toolkit:ColumnDataPoint">
                        <Border Background="Yellow" 
                                BorderBrush="Yellow" BorderThickness="0.5">
                            <Grid Background="{x:Null}">
                                <ToolTipService.ToolTip>
                                        <StackPanel Orientation="Horizontal">
                                              <ContentControl 
                                              Content ="{ TemplateBinding 
                                                  FormattedDependentValue }"/>
                                            <ContentControl Content =" ppm"/>
                                        </StackPanel>
                                </ToolTipService.ToolTip>
                                <Border BorderBrush="{x:Null}">
                                    <Border.Background>
                                        <LinearGradientBrush EndPoint="1.344,0.5" 
                                            StartPoint="-0.344,0.5">
                                            <GradientStop Color="White" Offset="0"/>
                                            <GradientStop Color="Yellow" Offset="0.5"/>
                                        </LinearGradientBrush>
                                    </Border.Background>
                                </Border>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            </Style>
        </ResourceDictionary>
        <ResourceDictionary>
            <Style x:Key="DataPointStyle" TargetType="Control">
                <Setter Property="Background" Value="Purple"/>
                <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="toolkit:ColumnDataPoint">
                        <Border Background="Purple" 
                              BorderBrush="Purple" BorderThickness="0.5">
                            <Grid Background="{x:Null}">
                                <ToolTipService.ToolTip>
                                        <StackPanel Orientation="Horizontal">
                                              <ContentControl 
                                              Content ="{ TemplateBinding 
                                                FormattedDependentValue }"/>
                                            <ContentControl Content =" ppm"/>
                                        </StackPanel>
                                </ToolTipService.ToolTip>
                                <Border BorderBrush="{x:Null}">
                                    <Border.Background>
                                        <LinearGradientBrush EndPoint="1.344,0.5" 
                                            StartPoint="-0.344,0.5">
                                            <GradientStop Color="White" Offset="0"/>
                                            <GradientStop Color="Purple" Offset="0.5"/>
                                        </LinearGradientBrush>
                                    </Border.Background>
                                </Border>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            </Style>
        </ResourceDictionary>
        <ResourceDictionary>
            <Style x:Key="DataPointStyle" TargetType="Control">
                <Setter Property="Background" Value="Orange"/>
                <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="toolkit:ColumnDataPoint">
                        <Border Background="Orange" 
                                 BorderBrush="Orange" 
                                 BorderThickness="0.5">
                            <Grid Background="{x:Null}">
                                <ToolTipService.ToolTip>
                                        <StackPanel Orientation="Horizontal">
                                              <ContentControl 
                                                Content ="{ TemplateBinding 
                                                   FormattedDependentValue }"/>
                                            <ContentControl Content =" ppm"/>
                                        </StackPanel>
                                </ToolTipService.ToolTip>
                                <Border BorderBrush="{x:Null}">
                                    <Border.Background>
                                        <LinearGradientBrush EndPoint="1.344,0.5" 
                                            StartPoint="-0.344,0.5">
                                            <GradientStop Color="White" Offset="0"/>
                                            <GradientStop Color="Orange" Offset="0.5"/>
                                        </LinearGradientBrush>
                                    </Border.Background>
                                </Border>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            </Style>
        </ResourceDictionary>
    </toolkit:ResourceDictionaryCollection>
</toolkit:Chart.Palette>

请注意,从上面的代码可以看出,Chart 绑定到一个类,但这次颜色是固定的,尽管仍然可以通过数据绑定 ControlTemplate 中的 Background 属性来动态更改颜色。

图表绑定的类是

public class GasName_Value
{
    public string Year { get; set; }
    public double GasValue1 { get; set; }
    public double GasValue2 { get; set; }
    public double GasValue3 { get; set; }
    public double GasValue4 { get; set; }
    public double GasValue5 { get; set; }
    public double GasValue6 { get; set; }
}

最终的 StackedColumnSeries 看起来像这样

Chart3.png

这些技术也可以应用于其他 StackedColumn Series,如 Stacked100ColumnSeriesStakedBarSeriesStacked100BarSeries,只需很少的修改。样式设置愉快!

© . All rights reserved.