WPFアプリケーションでPieChartとともにWPFツールキットチャートを使用しています。
円グラフ画像でデフォルトで白い背景を透明に変更したい。
それを達成するためのスタイルを与える方法
WPFアプリケーションでPieChartとともにWPFツールキットチャートを使用しています。
円グラフ画像でデフォルトで白い背景を透明に変更したい。
それを達成するためのスタイルを与える方法
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>
PlotAreaStyle
とはLegendStyle
、透明になるように変更されています。ControlTemplate
グラフの を変更し、問題のある要素をコメント アウトするだけで、プロット エリアの周囲の境界線が削除されBorder
ます。
ビジュアル ツリーを見ると、背景を透明に変更するには、グリッドと境界線の Background プロパティを変更する必要があることがわかります (下の図で黄色で強調表示されている要素)。
Loaded
そのために、イベントで色を変更できます。EdgePanel
最初に名前で検索する必要がありChartArea
、その後、グリッドと境界線の色を変更する必要があります。背景も透明に設定したい場合は、要素を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;
}
}