【问题标题】:How to give Style to WPF Toolkit Chart如何为 WPF 工具包图表赋予样式
【发布时间】:2013-03-03 09:58:21
【问题描述】:

我在我的 WPF 应用程序中使用 WPF 工具包图表和 PieChart。

我想在饼图图片中将默认白色背景更改为透明..

如何赋予风格以实现这一目标

【问题讨论】:

    标签: wpf wpftoolkit


    【解决方案1】:

    WPF 旨在允许您通过 XAML 设置控件样式;不是代码。也可以通过样式使饼图中的绘图区域和图例透明。不幸的是,绘图区域周围的边框无法使用属性来控制,而您必须修改整个控件模板。最后,使用样式可能与编写修改可视化树的代码一样乏味,但至少对我来说,它仍然是一种更简洁的方法。

    <chartingToolkit:Chart>
      <chartingToolkit:Chart.PlotAreaStyle>
        <Style TargetType="Grid">
          <Setter Property="Background" Value="Transparent"/>
        </Style>
      </chartingToolkit:Chart.PlotAreaStyle>
    
      <chartingToolkit:Chart.LegendStyle>
        <Style TargetType="visualizationToolkit:Legend">
          <Setter Property="Margin" Value="15,0"/>
          <Setter Property="VerticalAlignment" Value="Center"/>
          <Setter Property="BorderBrush" Value="Transparent"/>
          <Setter Property="Background" Value="Transparent"/>
        </Style>
      </chartingToolkit:Chart.LegendStyle>
    
      <chartingToolkit:Chart.Style>
        <Style TargetType="chartingToolkit:Chart">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="chartingToolkit:Chart">
                <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                  <Grid>
                    <Grid.RowDefinitions>
                      <RowDefinition Height="Auto" />
                      <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
    
                    <visualizationToolkit:Title Content="{TemplateBinding Title}" Style="{TemplateBinding TitleStyle}" />
    
                    <!-- Use a nested Grid to avoid possible clipping behavior resulting from ColumnSpan+Width=Auto -->
                    <Grid Grid.Row="1" Margin="0,15,0,15">
                      <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                      </Grid.ColumnDefinitions>
    
                      <visualizationToolkit:Legend x:Name="Legend" Title="{TemplateBinding LegendTitle}" Style="{TemplateBinding LegendStyle}" Grid.Column="1" />
                      <chartingprimitives:EdgePanel x:Name="ChartArea" Style="{TemplateBinding ChartAreaStyle}">
                        <Grid Canvas.ZIndex="-1" Style="{TemplateBinding PlotAreaStyle}" />
                        <!--<Border Canvas.ZIndex="10" BorderBrush="#FF919191" BorderThickness="1" />-->
                      </chartingprimitives:EdgePanel>
                    </Grid>
                  </Grid>
                </Border>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </chartingToolkit:Chart.Style>
    
      <chartingToolkit:PieSeries ... />
    </chartingToolkit:Chart>
    

    PlotAreaStyleLegendStyle 被修改为透明。通过修改图表的ControlTemplate 并简单地注释掉有问题的Border 元素来移除绘图区域周围的边框。

    【讨论】:

    • 嗨马丁,你的例子非常有用。如果我想将饼图更改为甜甜圈,或更改饼图的 3d 阴影,是否有文档知道哪些属性控制它?谢谢
    • @YafimSimanovsky:我提供这个答案已经七年了,恐怕我今天不知道如何回答你的问题。但是,如果我想调整现有的 WPF 控件,我会查看控件模板,看看是否可以实现我想要的,而无需像七年前那样从头开始重写控件。并且不要期望找到有关如何执行此操作的文档。如果控件设计者要提供修改 3D 阴影的方法,他们会添加一个属性来执行此操作,而不是记录如何自己修改控件模板。
    【解决方案2】:

    如果您查看可视化树,您会发现必须更改网格和边框的背景属性才能将背景更改为透明(下图中以黄色突出显示的元素)。

    为此,您可以在Loaded 事件中更改颜色。首先,您必须找到名称为ChartAreaEdgePanel,然后您必须更改网格和边框的颜色。如果您还想将Legend 的背景设置为透明,则必须找到Legend 元素并设置适当的属性。

    <DVC:Chart Canvas.Top="80" Canvas.Left="10" Name="mcChart" 
       Width="400" Height="250"
       Background="Orange"
       Loaded="mcChart_Loaded">            
        <DVC:Chart.Series>
            <DVC:PieSeries Title="Experience" 
                ItemsSource="{StaticResource FruitCollection}"
                IndependentValueBinding="{Binding Path=Name}"
                DependentValueBinding="{Binding Path=Share}">                
            </DVC:PieSeries>
        </DVC:Chart.Series>           
    </DVC:Chart>
    

    代码隐藏:

    private void mcChart_Loaded(object sender, RoutedEventArgs e)
    {
        EdgePanel ep = VisualHelper.FindChild<EdgePanel>(sender as Chart, "ChartArea");
        if (ep != null)
        {
            var grid = ep.Children.OfType<Grid>().FirstOrDefault();
            if (grid != null)
            {
                grid.Background = new SolidColorBrush(Colors.Transparent);
            }
    
            var border = ep.Children.OfType<Border>().FirstOrDefault();
            if (border != null)
            {
                border.BorderBrush = new SolidColorBrush(Colors.Transparent);
            }
        }
    
        Legend legend = VisualHelper.FindChild<Legend>(sender as Chart, "Legend");
        if (legend != null)
        {
            legend.Background = new SolidColorBrush(Colors.Transparent);
            legend.BorderBrush = new SolidColorBrush(Colors.Transparent);               
        }
    }
    

    帮助类在这种情况下查找子元素EdgePanel

    class VisualHelper
    {
        public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
        {
            if (parent == null) return null;
    
            T foundChild = null;
    
            int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < childrenCount; i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);
                T childType = child as T;
                if (childType == null)
                {
                    foundChild = FindChild<T>(child, childName);
                    if (foundChild != null) break;
                }
                else if (!string.IsNullOrEmpty(childName))
                {
                    var frameworkElement = child as FrameworkElement;
                    if (frameworkElement != null && frameworkElement.Name == childName)
                    {
                        foundChild = (T)child;
                        break;
                    }
                }
                else
                {
                    foundChild = (T)child;
                    break;
                }
            }
            return foundChild;
        }
    }
    

    【讨论】:

    • 但 CorrectAns、WrongAns、NotAttended 框背景没有改变
    • @AvinashSingh 再次检查我的答案 :) 我更改了 Loaded 事件处理程序的代码,将 Legend 的 bacground 属性设置为透明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多