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

■ UserControl 클래스 : 체크 버튼 사용하기

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


TestProject.zip


CheckButton.cs

 

 

using System;

using System.ComponentModel;

using System.Drawing;

using System.Drawing.Drawing2D;

using System.Windows.Forms;

 

namespace TestProject

{

    /// <summary>

    /// 체크 버튼

    /// </summary>

    [DefaultEvent("CheckedChanged")]

    public class CheckButton : UserControl

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Event

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

 

        #region 클릭시 이벤트 - Clicked

 

        /// <summary>

        /// 클릭시 이벤트

        /// </summary>

        public event EventHandler Clicked;

 

        #endregion

        #region 체크 변경시 이벤트 - CheckedChanged

 

        /// <summary>

        /// 체크 변경시 이벤트

        /// </summary>

        public event EventHandler CheckedChanged;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Enumeration

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

 

        #region 이미지 버튼 스타일 - CheckButtonStyle

 

        /// <summary>

        /// 이미지 버튼 스타일

        /// </summary>

        public enum CheckButtonStyle

        {

            /// <summary>

            /// DEFAULT

            /// </summary>

            Default,

 

            /// <summary>

            /// FLAT

            /// </summary>

            Flat

        };

 

        #endregion

 

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

 

        #region 이미지 버튼 상태 - CheckButtonState

 

        /// <summary>

        /// 이미지 버튼 상태

        /// </summary>

        private enum CheckButtonState { None, Hover, Pressed };

 

        #endregion

 

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

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

 

        #region Field

 

        /// <summary>

        /// 컨테이너

        /// </summary>

        private Container container = null;

 

        /// <summary>

        /// 버튼 스타일

        /// </summary>

        private CheckButtonStyle buttonStyle = CheckButtonStyle.Default;

 

        /// <summary>

        /// 버튼 상태

        /// </summary>

        private CheckButtonState buttonState = CheckButtonState.None;

 

        /// <summary>

        /// 코너 반지름

        /// </summary>

        private int cornerRadius = 8;

 

        /// <summary>

        /// 외부 테두리 경로

        /// </summary>

        private GraphicsPath outerBorderPath = null;

 

        /// <summary>

        /// 내부 테두리 경로

        /// </summary>

        private GraphicsPath innerBorderPath = null;

 

        /// <summary>

        /// 하이라이트 경로

        /// </summary>

        private GraphicsPath highlightPath = null;

 

        /// <summary>

        /// 버튼 색상 1

        /// </summary>

        private Color buttonColor1 = Color.Gray;

 

        /// <summary>

        /// 버튼 색상 브러시 1

        /// </summary>

        private SolidBrush buttonColorBrush1 = new SolidBrush(Color.Gray);

 

        /// <summary>

        /// 버튼 색상 2

        /// </summary>

        private Color buttonColor2 = Color.Gray;

 

        /// <summary>

        /// 버튼 색상 펜 2

        /// </summary>

        private Pen buttonColorPen2 = new Pen(Color.Gray);

 

        /// <summary>

        /// 하이라이트 색상

        /// </summary>

        private Color highlightColor = Color.White;

 

        /// <summary>

        /// 하이라이트 색상 펜

        /// </summary>

        private Pen highlightColorPen = new Pen(Color.White);

 

        /// <summary>

        /// 배경 이미지

        /// </summary>

        private Image backgroundImage = null;

 

        /// <summary>

        /// 체크 박스 표시 여부

        /// </summary>

        private bool showCheckBox = true;

 

        /// <summary>

        /// 체크 박스 표시 위치

        /// </summary>

        private Point checkBoxLocation = new Point(8, 8);

 

        /// <summary>

        /// 체크 여부

        /// </summary>

        private bool isChecked = false;

 

        /// <summary>

        /// 이미지 정렬

        /// </summary>

        private ContentAlignment imageAlignment = ContentAlignment.MiddleLeft;

 

        /// <summary>

        /// 이미지 크기

        /// </summary>

        private Size imageSize = new Size(24, 24);

 

        /// <summary>

        /// 이미지 사각형

        /// </summary>

        private Rectangle imageRectangle = new Rectangle(8, 8, 24, 24);

 

        /// <summary>

        /// 이미지

        /// </summary>

        private Image image = null;

 

        /// <summary>

        /// 제목 정렬

        /// </summary>

        private ContentAlignment titleAlignment = ContentAlignment.MiddleCenter;

 

        /// <summary>

        /// 제목 사각형

        /// </summary>

        private Rectangle titleRectangle;

 

        /// <summary>

        /// 제목 문자열 포맷

        /// </summary>

        private StringFormat titleStringFormat = null;

 

        /// <summary>

        /// 제목 색상

        /// </summary>

        private Color titleColor = Color.White;

 

        /// <summary>

        /// 제목

        /// </summary>

        private string title;

 

        /// <summary>

        /// FADE IN 타이머

        /// </summary>

        private Timer fadeInTimer = null;

 

        /// <summary>

        /// FADE OUT 타이머

        /// </summary>

        private Timer fadeOutTimer = null;

 

        /// <summary>

        /// 반짝임 투명도

        /// </summary>

        private int glowAlpha = 0;

 

        /// <summary>

        /// 반짝임 색상

        /// </summary>

        private Color glowColor = Color.White;

 

        /// <summary>

        /// 키로 호출 여부

        /// </summary>

        private bool calledByKey = false;

 

        /// <summary>

        /// 클릭 여부

        /// </summary>

        private bool isClicked = false;

 

        /// <summary>

        /// 대화 상자 결과

        /// </summary>

        private DialogResult dialogResult = DialogResult.None;

 

        #endregion

 

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

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

 

        #region 버튼 스타일 - ButtonStyle

 

        /// <summary>

        /// 버튼 스타일

        /// </summary>

        [Category("CheckButton")]

        public CheckButtonStyle ButtonStyle

        {

            get

            {

                return this.buttonStyle;

            }

            set

            {

                this.buttonStyle = value;

                

                Invalidate();

            }

        }

 

        #endregion

        #region 코너 반지름 - CornerRadius

 

        /// <summary>

        /// 코너 반지름

        /// </summary>

        [Category("CheckButton")]

        public int CornerRadius

        {

            get

            {

                return this.cornerRadius;

            }

            set

            {

                this.cornerRadius = value;

 

                SetOuterBorderPath(ClientRectangle, this.cornerRadius);

                

                Invalidate();

            }

        }

 

        #endregion

        #region 버튼 색상 1 - ButtonColor1

 

        /// <summary>

        /// 버튼 색상 1

        /// </summary>

        [Category("CheckButton")]

        public Color ButtonColor1

        {

            get

            {

                return this.buttonColor1;

            }

            set

            {

                this.buttonColor1 = value;

 

                this.buttonColorBrush1 = new SolidBrush(this.buttonColor1);

                

                Invalidate();

            }

        }

 

        #endregion

        #region 버튼 색상 2 - ButtonColor2

 

        /// <summary>

        /// 버튼 색상 2

        /// </summary>

        [Category("CheckButton")]

        public Color ButtonColor2

        {

            get

            {

                return this.buttonColor2;

            }

            set

            {

                this.buttonColor2 = value;

 

                this.buttonColorPen2 = new Pen(this.buttonColor2);

                

                Invalidate();

            }

        }

 

        #endregion

        #region 하이라이트 색상 - HighlightColor

 

        /// <summary>

        /// 하이라이트 색상

        /// </summary>

        [Category("CheckButton")]

        public Color HighlightColor

        {

            get

            {

                return this.highlightColor;

            }

            set

            {

                this.highlightColor = value;

 

                this.highlightColorPen = new Pen(this.highlightColor);

                

                Invalidate();

            }

        }

 

        #endregion

        #region 배경 이미지 - BackgroundImage

 

        /// <summary>

        /// 배경 이미지

        /// </summary>

        [Category("CheckButton")]

        public override Image BackgroundImage

        {

            get

            {

                return this.backgroundImage;

            }

            set

            {

                this.backgroundImage = value;

                

                Invalidate();

            }

        }

 

        #endregion

        #region 체크 박스 표시 여부 - ShowCheckBox

 

        /// <summary>

        /// 체크 박스 표시 여부

        /// </summary>

        [Category("CheckButton")]

        public bool ShowCheckBox

        {

            get

            {

                return this.showCheckBox;

            }

            set

            {

                this.showCheckBox = value;

                

                Invalidate();

            }

        }

 

        #endregion

        #region 체크 박스 표시 위치 - CheckBoxLocation

 

        /// <summary>

        /// 체크 박스 표시 위치

        /// </summary>

        [Category("CheckButton")]

        public Point CheckBoxLocation

        {

            get

            {

                return this.checkBoxLocation;

            }

            set

            {

                this.checkBoxLocation = value;

 

                Invalidate();

            }

        }

 

        #endregion

        #region 이미지 정렬 - ImageAlignment

 

        /// <summary>

        /// 이미지 정렬

        /// </summary>

        [Category("CheckButton")]

        public ContentAlignment ImageAlignment

        {

            get

            {

                return this.imageAlignment;

            }

            set

            {

                this.imageAlignment = value;

                

                Invalidate();

            }

        }

 

        #endregion

        #region 이미지 크기 - ImageSize

 

        /// <summary>

        /// 이미지 크기

        /// </summary>

        [Category("CheckButton")]

        public Size ImageSize

        {

            get

            {

                return this.imageSize;

            }

            set

            {

                this.imageSize = value;

 

                SetImageRectangle(this.imageSize);

                

                Invalidate();

            }

        }

 

        #endregion

        #region 이미지 - Image

 

        /// <summary>

        /// 이미지

        /// </summary>

        [Category("CheckButton")]

        public Image Image

        {

            get

            {

                return this.image;

            }

            set

            {

                this.image = value;

                

                Invalidate();

            }

        }

 

        #endregion

        #region 제목 정렬 - TitleAlignment

 

        /// <summary>

        /// 제목 정렬

        /// </summary>

        [Category("CheckButton")]

        public ContentAlignment TitleAlignment

        {

            get

            {

                return this.titleAlignment;

            }

            set

            {

                this.titleAlignment = value;

 

                SetTitleStringFormat(this.titleAlignment);

                

                Invalidate();

            }

        }

 

        #endregion

        #region 제목 색상 - TitleColor

 

        /// <summary>

        /// 제목 색상

        /// </summary>

        [Category("CheckButton")]

        public Color TitleColor

        {

            get

            {

                return this.titleColor;

            }

            set

            {

                this.titleColor = value;

                

                Invalidate();

            }

        }

 

        #endregion

        #region 제목 - Title

 

        /// <summary>

        /// 제목

        /// </summary>

        [Category("CheckButton")]

        public String Title

        {

            get

            {

                return this.title;

            }

            set

            {

                this.title = value;

 

                Invalidate();

            }

        }

 

        #endregion

        #region 반짝임 색상 - GlowColor

 

        /// <summary>

        /// 반짝임 색상

        /// </summary>

        [Category("CheckButton")]

        public Color GlowColor

        {

            get

            {

                return this.glowColor;

            }

            set

            {

                this.glowColor = value;

                

                Invalidate();

            }

        }

 

        #endregion

        #region 대화 상자 결과 - DialogResult

 

        /// <summary>

        /// 대화 상자 결과

        /// </summary>

        [Category("CheckButton")]

        public DialogResult DialogResult

        {

            get

            {

                return this.dialogResult;

            }

            set

            {

                this.dialogResult = value;

                

                Invalidate();

            }

        }

 

        #endregion

 

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

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

 

        #region 생성자 - CheckButton()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public CheckButton()

        {

            Name      = "CheckButton";

            Size      = new Size(100, 32);

            BackColor = Color.Transparent;

 

            SetHighlightPath(ClientRectangle, this.cornerRadius);

 

            SetOuterBorderPath(ClientRectangle, this.cornerRadius);

 

            SetInnerBorderPath(ClientRectangle, this.cornerRadius);

 

            SetTitleRectangle(ClientRectangle);

 

            SetTitleStringFormat(this.titleAlignment);

 

            this.SetStyle(ControlStyles.AllPaintingInWmPaint        , true);

            this.SetStyle(ControlStyles.DoubleBuffer                , true);

            this.SetStyle(ControlStyles.ResizeRedraw                , true);

            this.SetStyle(ControlStyles.Selectable                  , true);

            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);

            this.SetStyle(ControlStyles.UserPaint                   , true);

 

            this.fadeInTimer = new Timer();

 

            this.fadeInTimer.Interval  = 30;

 

            this.fadeOutTimer = new Timer();

 

            this.fadeOutTimer.Interval = 30;

 

            Resize                 += UserControl_Resize;

            Paint                  += UserControl_Paint;

            KeyDown                += UserControl_KeyDown;

            KeyUp                  += UserControl_KeyUp;

            MouseEnter             += UserControl_MouseEnter;

            MouseDown              += UserControl_MouseDown;

            MouseUp                += UserControl_MouseUp;

            MouseLeave             += UserControl_MouseLeave;

            this.fadeInTimer.Tick  += fadeInTimer_Tick;

            this.fadeOutTimer.Tick += fadeOutTimer_Tick;

        }

 

        #endregion

 

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

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

 

        #region 클릭시 이벤트 발생시키기 - FireClickedEvent()

 

        /// <summary>

        /// 클릭시 이벤트 발생시키기

        /// </summary>

        protected void FireClickedEvent()

        {

            Clicked?.Invoke(this, EventArgs.Empty);

        }

 

        #endregion

        #region 체크 변경시 이벤트 발생시키기 - FireCheckedChangedEvent()

 

        /// <summary>

        /// 체크 변경시 이벤트 발생시키기

        /// </summary>

        protected void FireCheckedChangedEvent()

        {

            CheckedChanged?.Invoke(this, EventArgs.Empty);

        }

 

        #endregion

        #region 리소스 해제하기 - Dispose(disposing)

 

        /// <summary>

        /// 리소스 해제하기

        /// </summary>

        protected override void Dispose(bool disposing)

        {

            if(disposing)

            {

                if(this.container != null)

                {

                    this.container.Dispose();

 

                    this.outerBorderPath?.Dispose();

 

                    this.innerBorderPath?.Dispose();

 

                    this.highlightPath?.Dispose();

 

                    this.buttonColorPen2?.Dispose();

 

                    this.highlightColorPen?.Dispose();

 

                    this.buttonColorBrush1?.Dispose();

                }

            }

 

            base.Dispose(disposing);

        }

 

        #endregion

 

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

        //////////////////////////////////////////////////////////////////////////////// Event

 

        #region 사용자 컨트롤 크기 변경시 처리하기 - UserControl_Resize(sender, e)

 

        /// <summary>

        /// 사용자 컨트롤 크기 변경시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void UserControl_Resize(object sender, EventArgs e)

        {

            Rectangle rectangle = ClientRectangle;

 

            rectangle.X -= 1;

            rectangle.Y -= 1;

 

            rectangle.Width  += 2;

            rectangle.Height += 2;

 

            using

            (

                GraphicsPath graphicsPath = GetShapePath

                (

                    rectangle,

                    this.cornerRadius,

                    this.cornerRadius,

                    this.cornerRadius,

                    this.cornerRadius

                )

            )

            {

                Region = new Region(graphicsPath);

            }

 

            SetOuterBorderPath(ClientRectangle, this.cornerRadius);

 

            SetInnerBorderPath(ClientRectangle, this.cornerRadius);

 

            SetHighlightPath(ClientRectangle, this.cornerRadius);

 

            SetTitleRectangle(ClientRectangle);

        }

 

        #endregion

        #region 사용자 컨트롤 키 DOWN시 처리하기 - UserControl_KeyDown(sender, e)

 

        /// <summary>

        /// 사용자 컨트롤 키 DOWN시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void UserControl_KeyDown(object sender, KeyEventArgs e)

        {

            if(e.KeyCode == Keys.Enter)

            {

                MouseEventArgs mouseEventArgs = new MouseEventArgs(MouseButtons.Left, 0, 0, 0, 0);

 

                UserControl_MouseDown(sender, mouseEventArgs);

            }

        }

 

        #endregion

        #region 사용자 컨트롤 키 UP시 처리하기 - UserControl_KeyUp(sender, e)

 

        /// <summary>

        /// 사용자 컨트롤 키 UP시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void UserControl_KeyUp(object sender, KeyEventArgs e)

        {

            if(e.KeyCode == Keys.Enter)

            {

                if(!this.isClicked)

                {

                    return;

                }

 

                MouseEventArgs mouseEventArgs = new MouseEventArgs(MouseButtons.Left, 0, 0, 0, 0);

 

                this.calledByKey = true;

 

                UserControl_MouseUp(sender, mouseEventArgs);

            }

        }

 

        #endregion

        #region 사용자 컨트롤 마우스 진입시 처리하기 - UserControl_MouseEnter(sender, e)

 

        /// <summary>

        /// 사용자 컨트롤 마우스 진입시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void UserControl_MouseEnter(object sender, EventArgs e)

        {

            this.buttonState = CheckButtonState.Hover;

 

            this.fadeOutTimer.Stop();

 

            this.fadeInTimer.Start();

        }

 

        #endregion

        #region 사용자 컨트롤 마우스 이탈시 처리하기 - UserControl_MouseLeave(sender, e)

 

        /// <summary>

        /// 사용자 컨트롤 마우스 이탈시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void UserControl_MouseLeave(object sender, EventArgs e)

        {

            this.buttonState = CheckButtonState.None;

 

            if(this.buttonStyle == CheckButtonStyle.Flat)

            {

                this.glowAlpha = 0;

            }

 

            this.fadeInTimer.Stop();

 

            this.fadeOutTimer.Start();

 

            this.isClicked = false;

        }

 

        #endregion

        #region 사용자 컨트롤 마우스 DOWN시 처리하기 - UserControl_MouseDown(sender, e)

 

        /// <summary>

        /// 사용자 컨트롤 마우스 DOWN시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void UserControl_MouseDown(object sender, MouseEventArgs e)

        {

            if(e.Button == MouseButtons.Left)

            {

                if(this.isClicked)

                {

                    return;

                }

 

                this.isClicked = true;

 

                this.buttonState = CheckButtonState.Pressed;

 

                if(this.buttonStyle != CheckButtonStyle.Flat)

                {

                    this.glowAlpha = 255;

                }

 

                this.fadeInTimer.Stop();

 

                this.fadeOutTimer.Stop();

 

                Invalidate();

            }

        }

 

        #endregion

        #region 사용자 컨트롤 마우스 UP시 처리하기 - UserControl_MouseUp(sender, e)

 

        /// <summary>

        /// 사용자 컨트롤 마우스 UP시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void UserControl_MouseUp(object sender, MouseEventArgs e)

        {

            if(e.Button == MouseButtons.Left)

            {

                this.buttonState = CheckButtonState.Hover;

 

                this.fadeInTimer.Stop();

 

                this.fadeOutTimer.Stop();

 

                Invalidate();

 

                if(this.calledByKey == true)

                {

                    OnClick(EventArgs.Empty);

                    

                    this.calledByKey = false;

                }

 

                this.isClicked = false;

 

                FireClickedEvent();

 

                this.isChecked = !this.isChecked;

 

                if(this.showCheckBox)

                {

                    FireCheckedChangedEvent();

                }

            }

        }

 

        #endregion

        #region 사용자 컨트롤 페인트시 처리하기 - UserControl_Paint(sender, e)

 

        /// <summary>

        /// 사용자 컨트롤 페인트시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void UserControl_Paint(object sender, PaintEventArgs e)

        {

            e.Graphics.SmoothingMode     = SmoothingMode.AntiAlias;

            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

 

            DrawBackgroundImage(e.Graphics);

            DrawHighlight(e.Graphics);

            DrawImage(e.Graphics);

            DrawTitle(e.Graphics);

            DrawGlow(e.Graphics);

            DrawInnerBorder(e.Graphics);

            DrawOuterBorder(e.Graphics);

            DrawCheckBox(e.Graphics);

        }

 

        #endregion

        #region FADE IN 타이머 틱 처리하기 - fadeInTimer_Tick(sender, e)

 

        /// <summary>

        /// FADE IN 타이머 틱 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void fadeInTimer_Tick(object sender, EventArgs e)

        {

            if(this.buttonStyle == CheckButtonStyle.Flat)

            {

                this.glowAlpha = 0;

            }

 

            if(this.glowAlpha + 30 >= 255)

            {

                this.glowAlpha = 255;

 

                this.fadeInTimer.Stop();

            }

            else

            {

                this.glowAlpha += 30;

            }

 

            Invalidate();

        }

 

        #endregion

        #region FADE OUT 타이머 틱 처리하기 - fadeOutTimer_Tick(sender, e)

 

        /// <summary>

        /// FADE OUT 타이머 틱 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void fadeOutTimer_Tick(object sender, EventArgs e)

        {

            if(this.buttonStyle == CheckButtonStyle.Flat)

            {

                this.glowAlpha = 0;

            }

 

            if(this.glowAlpha - 30 <= 0)

            {

                this.glowAlpha = 0;

 

                this.fadeOutTimer.Stop();

            }

            else

            {

                this.glowAlpha -= 30;

            }

 

            this.Invalidate();

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////// Function

 

        #region 도형 패스 구하기 - GetShapePath(rectangle, r1, r2, r3, r4)

 

        /// <summary>

        /// 도형 패스 구하기

        /// </summary>

        /// <param name="rectangle">사각형</param>

        /// <param name="r1">R1</param>

        /// <param name="r2">R2</param>

        /// <param name="r3">R3</param>

        /// <param name="r4">R4</param>

        /// <returns>도형 패스</returns>

        private GraphicsPath GetShapePath(RectangleF rectangle, float r1, float r2, float r3, float r4)

        {

            float x      = rectangle.X;

            float y      = rectangle.Y;

            float width  = rectangle.Width;

            float height = rectangle.Height;

 

            GraphicsPath graphicsPath = new GraphicsPath();

 

            graphicsPath.AddBezier(x, y + r1, x, y, x + r1, y, x + r1, y);

 

            graphicsPath.AddLine(x + r1, y, x + width - r2, y);

 

            graphicsPath.AddBezier(x + width - r2, y, x + width, y, x + width, y + r2, x + width, y + r2);

 

            graphicsPath.AddLine(x + width, y + r2, x + width, y + height - r3);

 

            graphicsPath.AddBezier

            (

                x + width,

                y + height - r3,

                x + width,

                y + height,

                x + width - r3,

                y + height,

                x + width - r3,

                y + height

            );

 

            graphicsPath.AddLine(x + width - r3, y + height, x + r4, y + height);

 

            graphicsPath.AddBezier(x + r4, y + height, x, y + height, x, y + height - r4, x, y + height - r4);

 

            graphicsPath.AddLine(x, y + height - r4, x, y + r1);

 

            return graphicsPath;

        }

 

        #endregion

        #region 하이라이트 경로 설정하기 - SetHighlightPath(clientRectangle, cornerRadius)

 

        /// <summary>

        /// 하이라이트 경로 설정하기

        /// </summary>

        /// <param name="clientRectangle">클라이언트 사각형</param>

        /// <param name="cornerRadius">코너 반지름</param>

        private void SetHighlightPath(Rectangle clientRectangle, int cornerRadius)

        {

            Rectangle rectangle = new Rectangle(0, 0, clientRectangle.Width, clientRectangle.Height / 2);

 

            GraphicsPath highlightPath = GetShapePath(rectangle, cornerRadius, cornerRadius, 0, 0);

 

            this.highlightPath?.Dispose();

 

            this.highlightPath = highlightPath;

        }

 

        #endregion

        #region 내부 테두리 경로 설정하기 - SetInnerBorderPath(clientRectangle, cornerRadius)

 

        /// <summary>

        /// 내부 테두리 경로 설정하기

        /// </summary>

        /// <param name="clientRectangle">클라이언트 사각형</param>

        /// <param name="cornerRadius">코너 반지름</param>

        private void SetInnerBorderPath(Rectangle clientRectangle, int cornerRadius)

        {

            Rectangle rectangle = clientRectangle;

 

            rectangle.X++;

            rectangle.Y++;

 

            rectangle.Width  -= 3;

            rectangle.Height -= 3;

 

            GraphicsPath innerBorderPath = GetShapePath

            (

                rectangle,

                cornerRadius,

                cornerRadius,

                cornerRadius,

                cornerRadius

            );

 

            this.innerBorderPath?.Dispose();

 

            this.innerBorderPath = innerBorderPath;

        }

 

        #endregion

        #region 외부 테두리 경로 설정하기 - SetOuterBorderPath(clientRectangle, cornerRadius)

 

        /// <summary>

        /// 외부 테두리 경로 설정하기

        /// </summary>

        /// <param name="clientRectangle">클라이언트 사각형</param>

        /// <param name="cornerRadius">코너 반지름</param>

        private void SetOuterBorderPath(Rectangle clientRectangle, float cornerRadius)

        {

            Rectangle rectangle = clientRectangle;

 

            rectangle.Width  -= 1;

            rectangle.Height -= 1;

 

            GraphicsPath outerBorderPath = GetShapePath

            (

                rectangle,

                cornerRadius,

                cornerRadius,

                cornerRadius,

                cornerRadius

            );

 

            this.outerBorderPath?.Dispose();

 

            this.outerBorderPath = outerBorderPath;

        }

 

        #endregion

        #region 이미지 사각형 설정하기 - SetImageRectangle(imageSize)

 

        /// <summary>

        /// 이미지 사각형 설정하기

        /// </summary>

        /// <param name="imageSize">이미지 크기</param>

        private void SetImageRectangle(Size imageSize)

        {

            Rectangle imageRectangle = new Rectangle(8, 8, imageSize.Width, imageSize.Height);

 

            switch(this.imageAlignment)

            {

                case ContentAlignment.TopCenter :

 

                    imageRectangle = new Rectangle

                    (

                        Width / 2 - imageSize.Width / 2,

                        8,

                        imageSize.Width,

                        imageSize.Height

                    );

 

                    break;

 

                case ContentAlignment.TopRight :

 

                    imageRectangle = new Rectangle

                    (

                        Width - 8 - imageSize.Width,

                        8,

                        imageSize.Width,

                        imageSize.Height

                    );

 

                    break;

 

                case ContentAlignment.MiddleLeft :

 

                    imageRectangle = new Rectangle

                    (

                        8,

                        Height / 2 - imageSize.Height / 2,

                        imageSize.Width,

                        imageSize.Height

                    );

 

                    break;

 

                case ContentAlignment.MiddleCenter :

 

                    imageRectangle = new Rectangle

                    (

                        Width  / 2 - imageSize.Width  / 2,

                        Height / 2 - imageSize.Height / 2,

                        imageSize.Width,

                        imageSize.Height

                    );

 

                    break;

 

                case ContentAlignment.MiddleRight :

 

                    imageRectangle = new Rectangle

                    (

                        Width  - 8 - imageSize.Width,

                        Height / 2 - imageSize.Height / 2,

                        imageSize.Width,

                        imageSize.Height

                    );

 

                    break;

 

                case ContentAlignment.BottomLeft :

 

                    imageRectangle = new Rectangle

                    (

                        8,

                        Height - 8 - imageSize.Height,

                        imageSize.Width,

                        imageSize.Height

                    );

 

                    break;

 

                case ContentAlignment.BottomCenter :

 

                    imageRectangle = new Rectangle

                    (

                        Width  / 2 - imageSize.Width / 2,

                        Height - 8 - imageSize.Height,

                        imageSize.Width,

                        imageSize.Height

                    );

 

                    break;

 

                case ContentAlignment.BottomRight :

 

                    imageRectangle = new Rectangle

                    (

                        Width  - 8 - imageSize.Width,

                        Height - 8 - imageSize.Height,

                        imageSize.Width,

                        imageSize.Height

                    );

 

                    break;

            }

 

            this.imageRectangle = imageRectangle;

        }

 

        #endregion

        #region 제목 사각형 설정하기 - SetTitleRectangle(clientRectangle)

 

        /// <summary>

        /// 제목 사각형 설정하기

        /// </summary>

        /// <param name="clientRectangle">클라이언트 사각형</param>

        private void SetTitleRectangle(Rectangle clientRectangle)

        {

            this.titleRectangle = new Rectangle(8, 4, clientRectangle.Width - 8, clientRectangle.Height - 8);

 

            //Rectangle rectangle = new Rectangle(8, 8, Width - 17, Height - 17);

        }

 

        #endregion

        #region 제목 문자열 포맷 설정하기 - SetTitleStringFormat(titleAlignment)

 

        /// <summary>

        /// 제목 문자열 포맷 설정하기

        /// </summary>

        /// <param name="titleAlignment">제목 정렬</param>

        private void SetTitleStringFormat(ContentAlignment titleAlignment)

        {

            StringFormat stringFormat = new StringFormat();

 

            stringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.LineLimit;

 

            switch(titleAlignment)

            {

                case ContentAlignment.TopLeft   :

                case ContentAlignment.TopCenter :

                case ContentAlignment.TopRight  :

 

                    stringFormat.LineAlignment = StringAlignment.Near;

 

                    break;

 

                case ContentAlignment.MiddleLeft   :

                case ContentAlignment.MiddleCenter :

                case ContentAlignment.MiddleRight  :

 

                    stringFormat.LineAlignment = StringAlignment.Center;

 

                    break;

 

                case ContentAlignment.BottomLeft   :

                case ContentAlignment.BottomCenter :

                case ContentAlignment.BottomRight  :

 

                    stringFormat.LineAlignment = StringAlignment.Far;

                    break;

            }

 

            switch(titleAlignment)

            {

                case ContentAlignment.TopLeft    :

                case ContentAlignment.MiddleLeft :

                case ContentAlignment.BottomLeft :

 

                    stringFormat.Alignment = StringAlignment.Near;

 

                    break;

 

                case ContentAlignment.TopCenter    :

                case ContentAlignment.MiddleCenter :

                case ContentAlignment.BottomCenter :

 

                    stringFormat.Alignment = StringAlignment.Center;

 

                    break;

 

                case ContentAlignment.TopRight    :

                case ContentAlignment.MiddleRight :

                case ContentAlignment.BottomRight :

 

                    stringFormat.Alignment = StringAlignment.Far;

 

                    break;

            }

 

            this.titleStringFormat = stringFormat;

        }

 

        #endregion

 

        #region 배경 이미지 그리기 - DrawBackgroundImage(graphics)

 

        /// <summary>

        /// 배경 이미지 그리기

        /// </summary>

        /// <param name="graphics">그래픽스</param>

        private void DrawBackgroundImage(Graphics graphics)

        {

            if(this.buttonStyle == CheckButtonStyle.Flat && this.buttonState == CheckButtonState.None)

            {

                return;

            }

 

            int alpha = (this.buttonState == CheckButtonState.Pressed) ? 204 : 127;

 

            graphics.FillPath(this.buttonColorBrush1, this.outerBorderPath);

 

            graphics.SetClip(this.innerBorderPath);

 

            if(this.backgroundImage != null)

            {

                graphics.DrawImage(this.backgroundImage, ClientRectangle);

            }

 

            graphics.ResetClip();

 

            using(SolidBrush solidBrush = new SolidBrush(Color.FromArgb(alpha, this.buttonColor2)))

            {

                graphics.FillPath(solidBrush, this.outerBorderPath);

            }

        }

 

        #endregion

        #region 하이라이트 그리기 - DrawHighlight(graphics)

 

        /// <summary>

        /// 하이라이트 그리기

        /// </summary>

        /// <param name="graphics">그래픽스</param>

        private void DrawHighlight(Graphics graphics)

        {

            if(!Enabled)

            {

                return;

            }

 

            if(this.buttonStyle == CheckButtonStyle.Flat && this.buttonState == CheckButtonState.None)

            {

                return;

            }

 

            int alpha = (buttonState == CheckButtonState.Pressed) ? 60 : 150;

 

            LinearGradientBrush highlightColorBrush = new LinearGradientBrush

            (

                this.highlightPath.GetBounds(),

                Color.FromArgb(alpha, this.highlightColor),

                Color.FromArgb(alpha / 3, this.highlightColor),

                LinearGradientMode.Vertical

            );

 

            graphics.FillPath(highlightColorBrush, this.highlightPath);

        }

 

        #endregion

        #region 이미지 그리기 - DrawImage(graphics)

 

        /// <summary>

        /// 이미지 그리기

        /// </summary>

        /// <param name="graphics">그래픽스</param>

        private void DrawImage(Graphics graphics)

        {

            if(this.image == null)

            {

                return;

            }

 

            graphics.DrawImage(this.image, this.imageRectangle);

        }

 

        #endregion

        #region 제목 그리기 - DrawTitle(graphics)

 

        /// <summary>

        /// 제목 그리기

        /// </summary>

        /// <param name="graphics">그래픽스</param>

        private void DrawTitle(Graphics graphics)

        {

            graphics.DrawString

            (

                this.title,

                Font,

                new SolidBrush(this.titleColor),

                this.titleRectangle,

                this.titleStringFormat

            );

        }

 

        #endregion

        #region 내부 테두리 그리기 - DrawInnerBorder(graphics)

 

        /// <summary>

        /// 내부 테두리 그리기

        /// </summary>

        /// <param name="graphics">그래픽스</param>

        private void DrawInnerBorder(Graphics graphics)

        {

            if(this.buttonStyle == CheckButtonStyle.Flat && this.buttonState == CheckButtonState.None)

            {

                return;

            }

 

            graphics.DrawPath(this.highlightColorPen, this.innerBorderPath);

        }

 

        #endregion

        #region 외부 테두리 그리기 - DrawOuterBorder(graphics)

 

        /// <summary>

        /// 외부 테두리 그리기

        /// </summary>

        /// <param name="graphics">그래픽스</param>

        private void DrawOuterBorder(Graphics graphics)

        {

            if(this.buttonStyle == CheckButtonStyle.Flat && this.buttonState == CheckButtonState.None)

            {

                return;

            }

 

            graphics.DrawPath(this.buttonColorPen2, this.outerBorderPath);

        }

 

        #endregion

        #region 체크 박스 그리기 - DrawCheckBox(graphics)

 

        /// <summary>

        /// 체크 박스 그리기

        /// </summary>

        /// <param name="graphics">그래픽스</param>

        private void DrawCheckBox(Graphics graphics)

        {

            if(this.showCheckBox)

            {

                System.Windows.Forms.VisualStyles.CheckBoxState state;

 

                if(this.isChecked)

                {

                    state = System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal;

                }

                else

                {

                    state = System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal;

                }

 

                CheckBoxRenderer.DrawCheckBox

                (

                    graphics,

                    this.checkBoxLocation,

                    state

                );

            }

        }

 

        #endregion

        #region GLOW 그리기 - DrawGlow(graphics)

 

        /// <summary>

        /// GLOW 그리기

        /// </summary>

        /// <param name="graphics">그래픽스</param>

        private void DrawGlow(Graphics graphics)

        {

            if(this.buttonState == CheckButtonState.Pressed || this.buttonState == CheckButtonState.None)

            {

                return;

            }

 

            graphics.SetClip(this.innerBorderPath);

 

            using(GraphicsPath graphicsPath = new GraphicsPath())

            {

                graphicsPath.AddEllipse(-5, this.Height / 2 - 10, Width + 11, Height + 11);

 

                using(PathGradientBrush pathGradientBrush = new PathGradientBrush(graphicsPath))

                {

                    pathGradientBrush.CenterColor    = Color.FromArgb(this.glowAlpha, this.glowColor);

                    pathGradientBrush.SurroundColors = new Color[] { Color.FromArgb(0, this.glowColor) };

 

                    graphics.FillPath(pathGradientBrush, graphicsPath);

                }

            }

 

            graphics.ResetClip();

        }

 

        #endregion

    }

}

 

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

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요