첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ FrameworkElement 클래스 : SimpleEllipse 클래스 만들기

----------------------------------------------------------------------------------------------------

using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Input;

using System.Windows.Media;

 

/// <summary>

/// 커스텀 타원

/// </summary>

public class SimpleEllipse : FrameworkElement

{

    //////////////////////////////////////////////////////////////////////////////////////////////////// Field

    ////////////////////////////////////////////////////////////////////////////////////////// Static

    //////////////////////////////////////////////////////////////////////////////// Public

 

    #region Field

 

    /// <summary>

    /// 채우기 속성

    /// </summary>

    public static readonly DependencyProperty FillProperty;

 

    /// <summary>

    /// 스트로크 속성

    /// </summary>

    public static readonly DependencyProperty StrokeProperty;

 

    #endregion

 

    ////////////////////////////////////////////////////////////////////////////////////////// Instance

    //////////////////////////////////////////////////////////////////////////////// Private

 

    #region Field

 

    /// <summary>

    /// 자식 UIElement

    /// </summary>

    private UIElement childUIElement;

 

    #endregion

 

    //////////////////////////////////////////////////////////////////////////////////////////////////// Property

    ////////////////////////////////////////////////////////////////////////////////////////// Public

 

    #region 채우기 - Fill

 

    /// <summary>

    /// 채우기

    /// </summary>

    public Brush Fill

    {

        set

        {

            SetValue(FillProperty, value);

        }

        get

        {

            return (Brush)GetValue(FillProperty);

        }

    }

 

    #endregion

    #region 스트로크 - Stroke

 

    /// <summary>

    /// 스트로크

    /// </summary>

    public Pen Stroke

    {

        set

        {

            SetValue(StrokeProperty, value);

        }

        get

        {

            return (Pen)GetValue(StrokeProperty);

        }

    }

 

    #endregion

    #region 자식 UIElement - Child

 

    /// <summary>

    /// 자식 UIElement

    /// </summary>

    public UIElement Child

    {

        set

        {

            if(this.childUIElement != null)

            {

                RemoveVisualChild(this.childUIElement);

 

                RemoveLogicalChild(this.childUIElement);

            }

 

            this.childUIElement = value;

 

            if(this.childUIElement != null)

            {

                AddVisualChild(this.childUIElement);

 

                AddLogicalChild(this.childUIElement);

            }

        }

        get

        {

            return this.childUIElement;

        }

    }

 

    #endregion

    #region 비주얼 자식 수 - VisualChildrenCount

 

    /// <summary>

    /// 비주얼 자식 수

    /// </summary>

    protected override int VisualChildrenCount

    {

        get

        {

            return Child != null ? 1 : 0;

        }

    }

 

    #endregion

 

    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

    ////////////////////////////////////////////////////////////////////////////////////////// Static

 

    #region 생성자 - SimpleEllipse()

 

    /// <summary>

    /// 생성자

    /// </summary>

    static SimpleEllipse()

    {

        FillProperty = DependencyProperty.Register

        (

            "Fill",

            typeof(Brush),

            typeof(SimpleEllipse),

            new FrameworkPropertyMetadata

            (

                null,

                FrameworkPropertyMetadataOptions.AffectsRender

            )

        );

 

        StrokeProperty = DependencyProperty.Register

        (

            "Stroke",

            typeof(Pen),

            typeof(SimpleEllipse),

            new FrameworkPropertyMetadata

            (

                null,

                FrameworkPropertyMetadataOptions.AffectsMeasure

            )

        );

    }

 

    #endregion

 

    //////////////////////////////////////////////////////////////////////////////////////////////////// Method

    ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

    #region 비주얼 자식 구하기 - GetVisualChild(index)

 

    /// <summary>

    /// 비주얼 자식 구하기

    /// </summary>

    /// <param name="index">인덱스</param>

    /// <returns>비주얼 자식</returns>

    protected override Visual GetVisualChild(int index)

    {

        if(index > 0 || Child == null)

        {

            throw new ArgumentOutOfRangeException("index");

        }

 

        return Child;

    }

 

    #endregion

 

    #region 측정하기 (오버라이딩) - MeasureOverride(availableSize)

 

    /// <summary>

    /// 측정하기 (오버라이딩)

    /// </summary>

    /// <param name="availableSize">이용 가능한 크기</param>

    /// <returns>측정 크기</returns>

    protected override Size MeasureOverride(Size availableSize)

    {

        Size desiredSize = new Size(0, 0);

 

        if(Stroke != null)

        {

            desiredSize.Width  += 2 * Stroke.Thickness;

            desiredSize.Height += 2 * Stroke.Thickness;

 

            availableSize.Width  = Math.Max(0, availableSize.Width  - 2 * Stroke.Thickness);

            availableSize.Height = Math.Max(0, availableSize.Height - 2 * Stroke.Thickness);

        }

 

        if(Child != null)

        {

            Child.Measure(availableSize);

 

            desiredSize.Width  += Child.DesiredSize.Width;

            desiredSize.Height += Child.DesiredSize.Height;

        }

 

        return desiredSize;

    }

 

    #endregion

 

    #region 배열하기 (오버라이딩) - ArrangeOverride(finalSize)

 

    /// <summary>

    /// 배열하기 (오버라이딩)

    /// </summary>

    /// <param name="finalSize">최종 크기</param>

    /// <returns>최종 크기</returns>

    protected override Size ArrangeOverride(Size finalSize)

    {

        if(Child != null)

        {

            Rect rect = new Rect

            (

                new Point

                (

                    (finalSize.Width  - Child.DesiredSize.Width ) / 2,

                    (finalSize.Height - Child.DesiredSize.Height) / 2

                ),

                Child.DesiredSize

            );

 

            Child.Arrange(rect);

        }

 

        return finalSize;

    }

 

    #endregion

 

    #region 렌더링 처리하기 - OnRender(drawingContext)

 

    /// <summary>

    /// 렌더링 처리하기

    /// </summary>

    /// <param name="drawingContext">DrawingContext</param>

    protected override void OnRender(DrawingContext drawingContext)

    {

        Size size = RenderSize;

 

        if(Stroke != null)

        {

            size.Width  = Math.Max(0, size.Width  - Stroke.Thickness);

            size.Height = Math.Max(0, size.Height - Stroke.Thickness);

        }

 

        drawingContext.DrawEllipse

        (

            Fill,

            Stroke,

            new Point(RenderSize.Width / 2, RenderSize.Height / 2),

            size.Width  / 2,

            size.Height / 2

        );

    }

 

    #endregion

}

----------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요