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

728x90
반응형
728x170

TestProject.zip
다운로드

▶ ITreeNode.cs

using System.Drawing;

namespace TestProject
{
    /// <summary>
    /// 트리 노드 인터페이스
    /// </summary>
    public interface ITreeNode
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        #region 크기 구하기 - GetSize(graphics, font)

        /// <summary>
        /// 크기 구하기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        /// <param name="font">폰트</param>
        /// <returns>크기</returns>
        SizeF GetSize(Graphics graphics, Font font);

        #endregion
        #region 포인트 위치 여부 구하기 - IsAtPoint(graphics, font, centerPoint, targetPoint)

        /// <summary>
        /// 포인트 위치 여부 구하기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        /// <param name="font">폰트</param>
        /// <param name="centerPoint">중심 포인트</param>
        /// <param name="targetPoint">타겟 포인트</param>
        /// <returns>포인트 위치 여부</returns>
        bool IsAtPoint(Graphics graphics, Font font, PointF centerPoint, PointF targetPoint);

        #endregion
        #region 그리기 - Draw(x, y, graphics, pen, backgroundBrush, textBrush, font)

        /// <summary>
        /// 그리기
        /// </summary>
        /// <param name="x">X 좌표</param>
        /// <param name="y">Y 좌표</param>
        /// <param name="graphics">그래픽스</param>
        /// <param name="pen">펜</param>
        /// <param name="backgroundBrush">배경 브러시</param>
        /// <param name="textBrush">텍스트 브러시</param>
        /// <param name="font">폰트</param>
        void Draw(float x, float y, Graphics graphics, Pen pen, Brush backgroundBrush, Brush textBrush, Font font);

        #endregion
    }
}

 

728x90

 

▶ CircleNode.cs

using System.Drawing;

namespace TestProject
{
    /// <summary>
    /// 원 노드
    /// </summary>
    public class CircleNode : ITreeNode
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 텍스트
        /// </summary>
        public string Text;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Consturctor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - CircleNode(text)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="text">텍스트</param>
        public CircleNode(string text)
        {
            Text = text;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 크기 구하기 - GetSize(graphics, font)

        /// <summary>
        /// 크기 구하기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        /// <param name="font">폰트</param>
        /// <returns>크기</returns>
        public SizeF GetSize(Graphics graphics, Font font)
        {
            return graphics.MeasureString(Text, font) + new SizeF(10, 10);
        }

        #endregion
        #region 포인트 위치 여부 구하기 - IsAtPoint(graphics, font, centerPoint, targetPoint)

        /// <summary>
        /// 포인트 위치 여부 구하기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        /// <param name="font">폰트</param>
        /// <param name="centerPoint">중심 포인트</param>
        /// <param name="targetPoint">타겟 포인트</param>
        /// <returns>포인트 위치 여부</returns>
        public bool IsAtPoint(Graphics graphics, Font font, PointF centerPoint, PointF targetPoint)
        {
            SizeF size = GetSize(graphics, font);

            targetPoint.X -= centerPoint.X;
            targetPoint.Y -= centerPoint.Y;

            float halfWidth  = size.Width  / 2;
            float halfHeight = size.Height / 2;

            return targetPoint.X * targetPoint.X / halfWidth / halfWidth + targetPoint.Y * targetPoint.Y / halfHeight / halfHeight <= 1;
        }

        #endregion
        #region 그리기 - Draw(x, y, graphics, pen, backgroundBrush, textBrush, font)

        /// <summary>
        /// 그리기
        /// </summary>
        /// <param name="x">X 좌표</param>
        /// <param name="y">Y 좌표</param>
        /// <param name="graphics">그래픽스</param>
        /// <param name="pen">펜</param>
        /// <param name="backgroundBrush">배경 브러시</param>
        /// <param name="textBrush">텍스트 브러시</param>
        /// <param name="font">폰트</param>
        public void Draw(float x, float y, Graphics graphics, Pen pen, Brush backgroundBrush, Brush textBrush, Font font)
        {
            SizeF size = GetSize(graphics, font);

            RectangleF rectangle = new RectangleF
            (
                x - size.Width / 2,
                y - size.Height / 2,
                size.Width,
                size.Height
            );

            graphics.FillEllipse(backgroundBrush, rectangle);

            graphics.DrawEllipse(pen, rectangle);

            using(StringFormat stringFormat = new StringFormat())
            {
                stringFormat.Alignment     = StringAlignment.Center;
                stringFormat.LineAlignment = StringAlignment.Center;

                graphics.DrawString(Text, font, textBrush, x, y, stringFormat);
            }
        }

        #endregion
    }
}

 

300x250

 

▶ TreeNode.cs

using System.Collections.Generic;
using System.Drawing;

namespace TestProject
{
    /// <summary>
    /// 트리 노드
    /// </summary>
    /// <typeparam name="TData">데이터 타입</typeparam>
    public class TreeNode<TData> where TData : ITreeNode
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 데이터
        /// </summary>
        public TData Data;

        /// <summary>
        /// 링크 가중치
        /// </summary>
        public int LinkWeight;

        /// <summary>
        /// 자식 노드 리스트
        /// </summary>
        public List<TreeNode<TData>> ChildNodeList = new List<TreeNode<TData>>();

        /// <summary>
        /// 폰트
        /// </summary>
        public Font Font = null;

        /// <summary>
        /// 펜
        /// </summary>
        public Pen Pen = Pens.Black;

        /// <summary>
        /// 폰트 브러시
        /// </summary>
        public Brush FontBrush = Brushes.Black;

        /// <summary>
        /// 링크 가중치 브러시
        /// </summary>
        public Brush LinkWeightBrush = Brushes.Red;

        /// <summary>
        /// 링크 가중치 폰트
        /// </summary>
        public Font LinkWeightFont = null;

        /// <summary>
        /// 배경 브러시
        /// </summary>
        public Brush BackgroundBrush = Brushes.White;

        /// <summary>
        /// 가중치 배경 브러시
        /// </summary>
        public Brush WeightBackgroundBrush = SystemBrushes.Control;

        /// <summary>
        /// 중심 포인트
        /// </summary>
        public PointF CenterPoint;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 수평 오프셋
        /// </summary>
        private const float HORIZONTAL_OFFSET = 30;

        /// <summary>
        /// 수직 오프셋
        /// </summary>
        private const float VERTICAL_OFFSET = 30;

        #endregion

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

        #region 생성자 - TreeNode(data, linkWeight, font, linkWeightFont)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="data">데이터</param>
        /// <param name="linkWeight">링크 가중치</param>
        /// <param name="font">폰트</param>
        /// <param name="linkWeightFont">링크 가중치 폰트</param>
        public TreeNode(TData data, int linkWeight, Font font, Font linkWeightFont)
        {
            Data           = data;
            LinkWeight     = linkWeight;
            Font           = font;
            LinkWeightFont = linkWeightFont;
        }

        #endregion
        #region 생성자 - TreeNode(data, linkWeight)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="data">데이터</param>
        /// <param name="linkWeight">링크 가중치</param>
        public TreeNode(TData data, int linkWeight) : this(data, linkWeight, new Font("나눔고딕코딩", 12), new Font("나눔고딕코딩", 12))
        {
        }

        #endregion
        #region 생성자 - TreeNode(data)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="data">데이터</param>
        public TreeNode(TData data) : this(data, int.MinValue)
        {
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 자식 추가하기 - AddChild(childNode, linkWeight)

        /// <summary>
        /// 자식 추가하기
        /// </summary>
        /// <param name="childNode">자식 노드</param>
        /// <param name="linkWeight">링크 가중치</param>
        public void AddChild(TreeNode<TData> childNode, int linkWeight)
        {
            ChildNodeList.Add(childNode);

            childNode.LinkWeight = linkWeight;
        }

        #endregion
        #region 자식 추가하기 - AddChild(childNode)

        /// <summary>
        /// 자식 추가하기
        /// </summary>
        /// <param name="childNode">자식 노드</param>
        public void AddChild(TreeNode<TData> childNode)
        {
            AddChild(childNode, int.MinValue);
        }

        #endregion
        #region 배열하기 - Arrange(graphics, minimumX, minimumY)

        /// <summary>
        /// 배열하기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        /// <param name="minimumX">X 최소값</param>
        /// <param name="minimumY">Y 최소값</param>
        public void Arrange(Graphics graphics, ref float minimumX, ref float minimumY)
        {
            SizeF size = Data.GetSize(graphics, Font);

            float x                 = minimumX;
            float biggestMinimumY   = minimumY + size.Height;
            float childTreeMinimumY = minimumY + size.Height + VERTICAL_OFFSET;

            foreach(TreeNode<TData> childNode in ChildNodeList)
            {
                float childMinimumY = childTreeMinimumY;

                childNode.Arrange(graphics, ref x, ref childMinimumY);

                if(biggestMinimumY < childMinimumY)
                {
                    biggestMinimumY = childMinimumY;
                }

                x += HORIZONTAL_OFFSET;
            }

            if(ChildNodeList.Count > 0)
            {
                x -= HORIZONTAL_OFFSET;
            }

            float childTreeWidth = x - minimumX;

            if(size.Width > childTreeWidth)
            {
                x = minimumX + (size.Width - childTreeWidth) / 2;

                foreach(TreeNode<TData> childNode in ChildNodeList)
                {
                    childNode.Arrange(graphics, ref x, ref childTreeMinimumY);

                    x += HORIZONTAL_OFFSET;
                }

                childTreeWidth = size.Width;
            }

            CenterPoint = new PointF
            (
                minimumX + childTreeWidth / 2,
                minimumY + size.Height    / 2
            );

            minimumX += childTreeWidth;

            minimumY = biggestMinimumY;
        }

        #endregion
        #region 트리 그리기 - DrawTree(graphics)

        /// <summary>
        /// 트리 그리기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        public void DrawTree(Graphics graphics)
        {
            DrawChildNodeLink(graphics);

            DrawChildNode(graphics);
        }

        #endregion
        #region 트리 그리기 - DrawTree(graphics, x, y)

        /// <summary>
        /// 트리 그리기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        /// <param name="x">X 좌표</param>
        /// <param name="y">y 좌표</param>
        public void DrawTree(Graphics graphics, ref float x, float y)
        {
            Arrange(graphics, ref x, ref y);

            DrawTree(graphics);
        }

        #endregion
        #region 노드 구하기 - GetNode(graphics, targetPoint)

        /// <summary>
        /// 노드 구하기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        /// <param name="targetPoint">타겟 포인트</param>
        /// <returns>노드</returns>
        public TreeNode<TData> GetNode(Graphics graphics, PointF targetPoint)
        {
            if(Data.IsAtPoint(graphics, Font, CenterPoint, targetPoint))
            {
                return this;
            }

            foreach(TreeNode<TData> childNode in ChildNodeList)
            {
                TreeNode<TData> hitNode = childNode.GetNode(graphics, targetPoint);

                if(hitNode != null)
                {
                    return hitNode;
                }
            }

            return null;
        }

        #endregion
        #region 노드 삭제하기 - DeleteNode(targetNode)

        /// <summary>
        /// 노드 삭제하기
        /// </summary>
        /// <param name="targetNode">타겟 노드</param>
        /// <returns>삭제 결과</returns>
        public bool DeleteNode(TreeNode<TData> targetNode)
        {
            foreach(TreeNode<TData> childNode in ChildNodeList)
            {
                if(childNode == targetNode)
                {
                    ChildNodeList.Remove(childNode);

                    return true;
                }

                if(childNode.DeleteNode(targetNode))
                {
                    return true;
                }
            }

            return false;
        }

        #endregion

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

        #region 링크 그리기 - DrawLink(graphics, linkWeight, point1, point2)

        /// <summary>
        /// 링크 그리기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        /// <param name="linkWeight">링크 가중치</param>
        /// <param name="point1">포인트 1</param>
        /// <param name="point2">포인트 2</param>
        private void DrawLink(Graphics graphics, int linkWeight, PointF point1, PointF point2)
        {
            graphics.DrawLine(Pen, point1, point2);

            if(linkWeight > int.MinValue)
            {
                PointF middlePoint = new PointF
                (
                    (point1.X + point2.X) / 2f,
                    (point1.Y + point2.Y) / 2f
                );

                SizeF size = graphics.MeasureString(linkWeight.ToString(), LinkWeightFont);

                RectangleF rectangle = new RectangleF
                (
                    middlePoint.X - size.Width  / 2f,
                    middlePoint.Y - size.Height / 2f,
                    size.Width,
                    size.Height
                );

                graphics.FillRectangle(WeightBackgroundBrush, rectangle);

                using(StringFormat stringFormat = new StringFormat())
                {
                    stringFormat.Alignment     = StringAlignment.Center;
                    stringFormat.LineAlignment = StringAlignment.Center;

                    graphics.DrawString(linkWeight.ToString(),

                    LinkWeightFont, LinkWeightBrush, rectangle, stringFormat);
                }
            }
        }

        #endregion
        #region 자식 노드 링크 그리기 - DrawChildNodeLink(graphics)

        /// <summary>
        /// 자식 노드 링크 그리기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        private void DrawChildNodeLink(Graphics graphics)
        {
            foreach(TreeNode<TData> childNode in ChildNodeList)
            {
                DrawLink(graphics, childNode.LinkWeight, CenterPoint, childNode.CenterPoint);

                childNode.DrawChildNodeLink(graphics);
            }
        }

        #endregion
        #region 자식 노드 그리기 - DrawChildNode(graphics)

        /// <summary>
        /// 자식 노드 그리기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        private void DrawChildNode(Graphics graphics)
        {
            Data.Draw(CenterPoint.X, CenterPoint.Y, graphics, Pen, BackgroundBrush, FontBrush, Font);

            foreach(TreeNode<TData> childNode in ChildNodeList)
            {
                childNode.DrawChildNode(graphics);
            }
        }

        #endregion
    }
}

 

▶ MainForm.cs

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 루트 노드
        /// </summary>
        private TreeNode<CircleNode> rootNode = new TreeNode<CircleNode>(new CircleNode("Root"));

        /// <summary>
        /// 선택 노드
        /// </summary>
        private TreeNode<CircleNode> selectedNode;

        #endregion

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

        #region 생성자 - MainForm()

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

            #region 이벤트를 설정한다.

            Load                            += Form_Load;
            this.addChildMenuItem.Click     += addChildMenuItem_Click;
            this.deleteNodeMenuItem.Click   += deleteNodeMenuItem_Click;
            this.canvasPictureBox.Resize    += canvasPictureBox_Resize;
            this.canvasPictureBox.Paint     += canvasPictureBox_Paint;
            this.canvasPictureBox.MouseDown += canvasPictureBox_MouseDown;
            this.canvasPictureBox.MouseMove += canvasPictureBox_MouseMove;

            #endregion
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 폼 로드시 처리하기 - Form_Load(sender, e)

        /// <summary>
        /// 폼 로드시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void Form_Load(object sender, EventArgs e)
        {
            TreeNode<CircleNode> aNode = new TreeNode<CircleNode>(new CircleNode("A"));
            TreeNode<CircleNode> bNode = new TreeNode<CircleNode>(new CircleNode("B"));
            TreeNode<CircleNode> cNode = new TreeNode<CircleNode>(new CircleNode("C"));
            TreeNode<CircleNode> dNode = new TreeNode<CircleNode>(new CircleNode("D"));
            TreeNode<CircleNode> eNode = new TreeNode<CircleNode>(new CircleNode("E"));
            TreeNode<CircleNode> fNode = new TreeNode<CircleNode>(new CircleNode("F"));
            TreeNode<CircleNode> gNode = new TreeNode<CircleNode>(new CircleNode("G"));
            TreeNode<CircleNode> hNode = new TreeNode<CircleNode>(new CircleNode("H"));

            Random random = new Random();

            this.rootNode.AddChild(aNode, random.Next(1, 100));
            this.rootNode.AddChild(bNode, random.Next(1, 100));

            aNode.AddChild(cNode, random.Next(1, 100));
            aNode.AddChild(dNode, random.Next(1, 100));
            bNode.AddChild(eNode, random.Next(1, 100));
            bNode.AddChild(fNode, random.Next(1, 100));
            bNode.AddChild(gNode, random.Next(1, 100));
            eNode.AddChild(hNode, random.Next(1, 100));

            ArrangeTree();
        }

        #endregion
        #region 자식 추가하기 메뉴 항목 클릭시 처리하기 - addChildMenuItem_Click(sender, e)

        /// <summary>
        /// 자식 추가하기 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void addChildMenuItem_Click(object sender, EventArgs e)
        {
            AddChildNodeForm form = new AddChildNodeForm();

            if(form.ShowDialog(this) == DialogResult.OK)
            {
                string text   = form.NodeText;
                int    weight = form.LinkWeight;

                TreeNode<CircleNode> childNode = new TreeNode<CircleNode>(new CircleNode(text));

                this.selectedNode.AddChild(childNode, weight);

                ArrangeTree();
            }
        }

        #endregion
        #region 노드 삭제하기 메뉴 항목 클릭시 처리하기 - deleteNodeMenuItem_Click(sender, e)

        /// <summary>
        /// 노드 삭제하기 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void deleteNodeMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show
            (
                "노드를 삭제하시겠습니까?",
                "확인",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question
            );

            if(result == DialogResult.Yes)
            {
                this.rootNode.DeleteNode(this.selectedNode);

                ArrangeTree();
            }
        }

        #endregion
        #region 캔버스 픽처 박스 크기 조정시 처리하기 - canvasPictureBox_Resize(sender, e)

        /// <summary>
        /// 캔버스 픽처 박스 크기 조정시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void canvasPictureBox_Resize(object sender, EventArgs e)
        {
            ArrangeTree();
        }

        #endregion
        #region 캔버스 픽처 박스 마우스 이동시 처리하기 - canvasPictureBox_MouseMove(sender, e)

        /// <summary>
        /// 캔버스 픽처 박스 마우스 이동시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void canvasPictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            SetSelectedNode(e.Location);

            if(this.selectedNode == null)
            {
                this.statusLabel.Text = string.Empty;
            }
            else
            {
                this.statusLabel.Text = this.selectedNode.Data.Text;
            }
        }

        #endregion
        #region 캔버스 픽처 박스 마우스 DOWN 처리하기 - canvasPictureBox_MouseDown(sender, e)

        /// <summary>
        /// 캔버스 픽처 박스 마우스 DOWN 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void canvasPictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            if(e.Button != MouseButtons.Right)
            {
                return;
            }

            SetSelectedNode(e.Location);

            if(this.selectedNode != null)
            {
                this.deleteNodeMenuItem.Enabled = (this.selectedNode != this.rootNode);

                this.contextMenuStrip.Show(this, e.Location);
            }
        }

        #endregion
        #region 캔버스 픽처 박스 페인트시 처리하기 - canvasPictureBox_Paint(sender, e)

        /// <summary>
        /// 캔버스 픽처 박스 페인트시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void canvasPictureBox_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.SmoothingMode     = SmoothingMode.AntiAlias;
            e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

            this.rootNode.DrawTree(e.Graphics);
        }

        #endregion

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

        #region 트리 정렬하기 - ArrangeTree()

        /// <summary>
        /// 트리 정렬하기
        /// </summary>
        private void ArrangeTree()
        {
            using(Graphics graphics = this.canvasPictureBox.CreateGraphics())
            {
                float minimumX = 0;
                float minimumY = 0;

                this.rootNode.Arrange(graphics, ref minimumX, ref minimumY);

                minimumX = (this.ClientSize.Width - minimumX) / 2;
                minimumY = 10;

                this.rootNode.Arrange(graphics, ref minimumX, ref minimumY);
            }

            this.canvasPictureBox.Refresh();
        }

        #endregion
        #region 선택 노드 설정하기 - SetSelectedNode(PointF mousePoint)

        /// <summary>
        /// 선택 노드 설정하기
        /// </summary>
        /// <param name="mousePoint">마우스 포인트</param>
        private void SetSelectedNode(PointF mousePoint)
        {
            using(Graphics graphics = this.canvasPictureBox.CreateGraphics())
            {
                this.selectedNode = this.rootNode.GetNode(graphics, mousePoint);
            }
        }

        #endregion
    }
}
728x90
반응형
그리드형
Posted by 사용자 icodebroker

댓글을 달아 주세요