我想创建一个自定义控件以显示饼图。我有一个 PieSlice 类(我从 WinRT 工具包项目中获得):
public class PieSlice : Path
{
#region StartAngle
public static readonly DependencyProperty StartAngleProperty =
DependencyProperty.Register(
"StartAngle",
typeof(double),
typeof(PieSlice),
new PropertyMetadata(
0d,
new PropertyChangedCallback(OnStartAngleChanged)));
public double StartAngle
{
get { return (double)GetValue(StartAngleProperty); }
set { SetValue(StartAngleProperty, value); }
}
private static void OnStartAngleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var target = (PieSlice)sender;
var oldStartAngle = (double)e.OldValue;
var newStartAngle = (double)e.NewValue;
target.OnStartAngleChanged(oldStartAngle, newStartAngle);
}
private void OnStartAngleChanged(double oldStartAngle, double newStartAngle)
{
UpdatePath();
}
#endregion
#region EndAngle
public static readonly DependencyProperty EndAngleProperty =
DependencyProperty.Register(
"EndAngle",
typeof(double),
typeof(PieSlice),
new PropertyMetadata(
0d,
new PropertyChangedCallback(OnEndAngleChanged)));
public double EndAngle
{
get { return (double)GetValue(EndAngleProperty); }
set { SetValue(EndAngleProperty, value); }
}
private static void OnEndAngleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var target = (PieSlice)sender;
var oldEndAngle = (double)e.OldValue;
var newEndAngle = (double)e.NewValue;
target.OnEndAngleChanged(oldEndAngle, newEndAngle);
}
private void OnEndAngleChanged(double oldEndAngle, double newEndAngle)
{
UpdatePath();
}
#endregion
#region Radius
public static readonly DependencyProperty RadiusProperty =
DependencyProperty.Register(
"Radius",
typeof(double),
typeof(PieSlice),
new PropertyMetadata(
0d,
new PropertyChangedCallback(OnRadiusChanged)));
public double Radius
{
get { return (double)GetValue(RadiusProperty); }
set { SetValue(RadiusProperty, value); }
}
private static void OnRadiusChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var target = (PieSlice)sender;
var oldRadius = (double)e.OldValue;
var newRadius = (double)e.NewValue;
target.OnRadiusChanged(oldRadius, newRadius);
}
private void OnRadiusChanged(double oldRadius, double newRadius)
{
this.Width = this.Height = 2 * Radius;
UpdatePath();
}
#endregion
private void UpdatePath()
{
var pathGeometry = new PathGeometry();
var pathFigure = new PathFigure();
pathFigure.StartPoint = new Point(Radius, Radius);
pathFigure.IsClosed = true;
// Starting Point
var lineSegment =
new LineSegment
{
Point = new Point(
Radius + Math.Sin(StartAngle * Math.PI / 180) * Radius,
Radius - Math.Cos(StartAngle * Math.PI / 180) * Radius)
};
// Arc
var arcSegment = new ArcSegment();
arcSegment.IsLargeArc = (EndAngle - StartAngle) >= 180.0;
arcSegment.Point =
new Point(
Radius + Math.Sin(EndAngle * Math.PI / 180) * Radius,
Radius - Math.Cos(EndAngle * Math.PI / 180) * Radius);
arcSegment.Size = new Size(Radius, Radius);
arcSegment.SweepDirection = SweepDirection.Clockwise;
pathFigure.Segments.Add(lineSegment);
pathFigure.Segments.Add(arcSegment);
pathGeometry.Figures.Add(pathFigure);
this.Data = pathGeometry;
this.InvalidateArrange();
}
}
现在我正在尝试创建一个可以包含多个饼图的控件
public class Pie : Control
{
#region Items Source
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register(
"ItemsSource",
typeof(IEnumerable),
typeof(Pie),
new PropertyMetadata(
null,
new PropertyChangedCallback(OnItemsSourceChanged)));
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
private static void OnItemsSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var target = (Pie)sender;
var oldItemsSource = (IEnumerable)e.OldValue;
var newItemsSource = (IEnumerable)e.NewValue;
target.OnItemsSourceChanged(oldItemsSource, newItemsSource);
}
private void OnItemsSourceChanged(IEnumerable oldItemsSource, IEnumerable newItemsSource)
{
UpdatePieSlices();
}
#endregion
public Pie()
{
this.DefaultStyleKey = typeof(Pie);
}
private void UpdatePieSlices()
{
double startAngle = 0;
foreach (KeyValuePair<string, double> item in ItemsSource)
{
PieSlice slice = new PieSlice()
{
Fill = new SolidColorBrush(Colors.Red),
Radius = 100, StartAngle = startAngle,
EndAngle = (item.Value / 100.0) * 360
};
startAngle = (item.Value / 100.0) * 360;
}
}
}
ItemsSource 是KeyValuePair<string, int>
代表切片名称和百分比的集合。我想显示切片,但我不知道如何...
编辑 :
我已经尝试过了,但它不起作用
<Style TargetType="control:Pie">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="control:Pie">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ItemsControl
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
ItemsSource="{Binding Path=ItemsSource}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid></Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>