첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
본 블로그는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 블로그 콘텐츠 향상을 위해 쓰여집니다.

728x90
반응형
728x170

TestProject.zip
0.01MB

▶ PieSlice.cs

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 
    }
}

 

728x90

 

▶ MainWindow.xaml

<Window x:Class="TestProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestProject"
    Width="800"
    Height="600"
    Title="DependencyProperty 클래스 : OverrideMetadata 메소드를 사용해 표준 의존 속성 디폴트 값 설정하기"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <Grid>
        <local:PieSlice
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Margin="5"
            Height="300"
            Width="300"
            StrokeThickness="3"
            StartAngle="0"
            EndAngle="60" />
    </Grid>
</Window>
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요