첨부 소스 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
다운로드

▶ 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"
    Width="800"
    Height="600"
    Title="마우스 드래그를 사용해 원 그리기"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <Canvas x:Name="canvas" />
</Window>

 

728x90

 

▶ MainWindow.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace TestProject
{
    /// <summary>
    /// 메인 윈도우
    /// </summary>
    public partial class MainWindow : Window
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 그리기 여부
        /// </summary>
        private bool isDrawing;

        /// <summary>
        /// 드래그 여부
        /// </summary>
        private bool isDragging;

        /// <summary>
        /// 중심점
        /// </summary>
        private Point centerPoint;

        /// <summary>
        /// 원
        /// </summary>
        private Ellipse ellipse;

        /// <summary>
        /// 드래그 프레임워크 엘리먼트
        /// </summary>
        private FrameworkElement draggingFrameworkElement;

        /// <summary>
        /// 마우스 시작점
        /// </summary>
        private Point mouseStartPoint;

        /// <summary>
        /// 드래그 프레임워크 엘리먼트 시작점
        /// </summary>
        private Point draggingFrameworkElementStartPoint;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainWindow()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Protected

        #region 마우스 왼쪽 버튼 다운시 처리하기 - OnMouseLeftButtonDown(e)

        /// <summary>
        /// 마우스 왼쪽 버튼 다운시 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);

            if(this.isDragging)
            {
                return;
            }

            this.centerPoint = e.GetPosition(this.canvas);

            this.ellipse = new Ellipse();

            this.ellipse.Stroke          = SystemColors.WindowTextBrush;
            this.ellipse.StrokeThickness = 1;
            this.ellipse.Width           = 0;
            this.ellipse.Height          = 0;

            this.canvas.Children.Add(this.ellipse);

            Canvas.SetLeft(this.ellipse, this.centerPoint.X);
            Canvas.SetTop (this.ellipse, this.centerPoint.Y);

            CaptureMouse();

            this.isDrawing = true;
        }

        #endregion
        #region 마우스 오른쪽 버튼 다운시 처리하기 - OnMouseRightButtonDown(e)

        /// <summary>
        /// 마우스 오른쪽 버튼 다운시 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnMouseRightButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseRightButtonDown(e);

            if(this.isDrawing)
            {
                return;
            }

            this.mouseStartPoint = e.GetPosition(this.canvas);

            this.draggingFrameworkElement = this.canvas.InputHitTest(this.mouseStartPoint) as FrameworkElement;

            if(this.draggingFrameworkElement != null)
            {
                this.draggingFrameworkElementStartPoint = new Point
                (
                    Canvas.GetLeft(this.draggingFrameworkElement),
                    Canvas.GetTop (this.draggingFrameworkElement)
                );

                CaptureMouse();

                this.isDragging = true;
            }
        }

        #endregion
        #region 마우스 다운시 처리하기 - OnMouseDown(e)

        /// <summary>
        /// 마우스 다운시 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);

            if(e.ChangedButton == MouseButton.Middle)
            {
                Shape shape = this.canvas.InputHitTest(e.GetPosition(this.canvas)) as Shape;

                if(shape != null)
                {
                    shape.Fill = (shape.Fill == Brushes.Red ? Brushes.Transparent : Brushes.Red);
                }
            }
        }

        #endregion
        #region 마우스 이동시 처리하기 - OnMouseMove(e)

        /// <summary>
        /// 마우스 이동시 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            Point currentMousePoint = e.GetPosition(this.canvas);

            if(this.isDrawing)
            {
                double radius = Math.Sqrt(Math.Pow(this.centerPoint.X - currentMousePoint.X, 2) + Math.Pow(this.centerPoint.Y - currentMousePoint.Y, 2));

                Canvas.SetLeft(this.ellipse, this.centerPoint.X - radius);
                Canvas.SetTop (this.ellipse, this.centerPoint.Y - radius);

                this.ellipse.Width  = 2 * radius;
                this.ellipse.Height = 2 * radius;
            }
            else if(this.isDragging)
            {
                Canvas.SetLeft(this.draggingFrameworkElement, this.draggingFrameworkElementStartPoint.X + currentMousePoint.X - this.mouseStartPoint.X);
                Canvas.SetTop (this.draggingFrameworkElement, this.draggingFrameworkElementStartPoint.Y + currentMousePoint.Y - this.mouseStartPoint.Y);
            }
        }

        #endregion
        #region 마우스 버튼 해제시 처리하기 - OnMouseUp(e)

        /// <summary>
        /// 마우스 버튼 해제시 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnMouseUp(MouseButtonEventArgs e)
        {
            base.OnMouseUp(e);

            if(this.isDrawing && e.ChangedButton == MouseButton.Left)
            {
                this.ellipse.Stroke          = Brushes.Blue;
                this.ellipse.StrokeThickness = Math.Min(24, this.ellipse.Width / 2);
                this.ellipse.Fill            = Brushes.Red;

                this.isDrawing = false;

                ReleaseMouseCapture();
            }
            else if(this.isDragging && e.ChangedButton == MouseButton.Right)
            {
                this.isDragging = false;

                ReleaseMouseCapture();
            }
        }

        #endregion
        #region 텍스트 입력시 처리하기 - OnTextInput(e)

        /// <summary>
        /// 텍스트 입력시 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnTextInput(TextCompositionEventArgs e)
        {
            base.OnTextInput(e);

            if(e.Text.IndexOf('\x1B') != -1)
            {
                if(this.isDrawing)
                {
                    ReleaseMouseCapture();
                }
                else if(this.isDragging)
                {
                    Canvas.SetLeft(this.draggingFrameworkElement, this.draggingFrameworkElementStartPoint.X);
                    Canvas.SetTop (this.draggingFrameworkElement, this.draggingFrameworkElementStartPoint.Y);

                    ReleaseMouseCapture();
                }
            }
        }

        #endregion
        #region 마우스 캡처 상실시 처리하기 - OnLostMouseCapture(e)

        /// <summary>
        /// 마우스 캡처 상실시 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnLostMouseCapture(MouseEventArgs e)
        {
            base.OnLostMouseCapture(e);

            if(this.isDrawing)
            {
                this.canvas.Children.Remove(this.ellipse);

                this.isDrawing = false;
            }

            if(this.isDragging)
            {
                this.isDragging = false;
            }
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요