using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace TestProject
{
/// <summary>
/// 파이 슬라이스
/// </summary>
public class PieSlice : Shape
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 시작 각도 속성 - StartAngleProperty
/// <summary>
/// 시작 각도 속성
/// </summary>
public static readonly DependencyProperty StartAngleProperty = DependencyProperty.Register
(
"StartAngle",
typeof(double),
typeof(PieSlice),
new FrameworkPropertyMetadata
(
0.0,
FrameworkPropertyMetadataOptions.AffectsRender,
null,
new CoerceValueCallback(AnglePropertyCoerceValueCallback)
)
);
#endregion
#region 종료 각도 속성 - EndAngleProperty
/// <summary>
/// 종료 각도 속성
/// </summary>
public static readonly DependencyProperty EndAngleProperty = DependencyProperty.Register
(
"EndAngle",
typeof(double),
typeof(PieSlice),
new FrameworkPropertyMetadata
(
90.0,
FrameworkPropertyMetadataOptions.AffectsRender,
null,
new CoerceValueCallback(AnglePropertyCoerceValueCallback)
)
);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 시작 각도 - StartAngle
/// <summary>
/// 시작 각도
/// </summary>
public double StartAngle
{
get
{
return (double)GetValue(StartAngleProperty);
}
set
{
SetValue(StartAngleProperty, value);
}
}
#endregion
#region 종료 각도 - EndAngle
/// <summary>
/// 종료 각도
/// </summary>
public double EndAngle
{
get
{
return (double)GetValue(EndAngleProperty);
}
set
{
SetValue(EndAngleProperty, value);
}
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 정의 지오메트리 - DefiningGeometry
/// <summary>
/// 정의 지오메트리
/// </summary>
protected override Geometry DefiningGeometry
{
get
{
double maximumWidth = Math.Max(0.0, RenderSize.Width - StrokeThickness);
double maximumHeight = Math.Max(0.0, RenderSize.Height - StrokeThickness);
double xStart = maximumWidth / 2.0 * Math.Cos(StartAngle * Math.PI / 180.0);
double yStart = maximumHeight / 2.0 * Math.Sin(StartAngle * Math.PI / 180.0);
double xEnd = maximumWidth / 2.0 * Math.Cos(EndAngle * Math.PI / 180.0);
double yEnd = maximumHeight / 2.0 * Math.Sin(EndAngle * Math.PI / 180.0);
StreamGeometry geometry = new StreamGeometry();
using(StreamGeometryContext context = geometry.Open())
{
context.BeginFigure
(
new Point
(
(RenderSize.Width / 2.0) + xStart,
(RenderSize.Height / 2.0) - yStart
),
true,
true
);
context.ArcTo
(
new Point
(
(RenderSize.Width / 2.0) + xEnd,
(RenderSize.Height / 2.0) - yEnd
),
new Size
(
maximumWidth / 2.0,
maximumHeight / 2.0
),
0.0,
(EndAngle - StartAngle) > 180,
SweepDirection.Counterclockwise,
true,
false
);
context.LineTo
(
new Point
(
(RenderSize.Width / 2.0),
(RenderSize.Height / 2.0)
),
true,
false
);
}
return geometry;
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Static
#region 생성자 - PieSlice()
/// <summary>
/// 생성자
/// </summary>
static PieSlice()
{
Brush brush = new SolidColorBrush(Color.FromArgb(255, 6, 176, 37));
brush.Freeze();
StrokeProperty.OverrideMetadata(typeof(PieSlice), new FrameworkPropertyMetadata(brush));
FillProperty.OverrideMetadata(typeof(PieSlice), new FrameworkPropertyMetadata(brush));
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 각도 속성 값 강제시 콜백 처리하기 - AnglePropertyCoerceValueCallback(d, value)
/// <summary>
/// 각도 속성 값 강제시 콜백 처리하기
/// </summary>
/// <param name="d">의존 객체</param>
/// <param name="value">값</param>
/// <returns>처리 결과</returns>
private static object AnglePropertyCoerceValueCallback(DependencyObject d, object value)
{
double angle = (double)value;
angle = Math.Min(angle, 359.9);
angle = Math.Max(angle, 0.0 );
return angle;
}
#endregion
}
}