반응형
 

도킹 기능을 사용하려고 
맨날맑음 님께서 제공해주신 Tip을  보다가 수정을 좀 해봤습니다. ^^
기본 로직은 신의아그니스님이 올려주신 것처럼 좌표를 비교해서 도킹합니다.
 
 

 
FormUtil.cs
 

using System;

using System.Windows.Forms;

using System.Drawing;

 

// Author RevMinho

 

namespace DockingTest

{

    class FormUtil

    {

        private Form current;   //현재 폼 윈도우

        private Point prevLoc;  //폼의 이전 위치

 

        public FormUtil(Form form)

        {

            current = form;

            prevLoc = form.Location;

        }

 

        public void docking(Form target, int dockGap)

        {

            // 만약 소유한 폼들이 있고 도킹되어 있다면 함께 이동한다.

            foreach (Form temp in current.OwnedForms)

            {

                if (isDocked(temp))

                {

                    temp.SetDesktopLocation(

                        temp.Location.X + (current.Location.X - prevLoc.X),

                        temp.Location.Y + (current.Location.Y - prevLoc.Y));

                }

            }

 

            // 폼의 현재위치를 저장해둔다.

            prevLoc = current.Location;

 

            // 도킹 대상 폼윈도우의 오른쪽에 접근시

            if (checkRange(current.Left, target.Right, dockGap) && checkYLine(target))

            {

                current.Left = target.Right;

            }

 

            // 도킹 대상 폼윈도우의 왼쪽에 접근시

            if (checkRange(current.Right, target.Left, dockGap) && checkYLine(target))

            {

                current.Left = target.Left - current.Width;

            }

 

            // 도킹 대상 폼윈도우의 아래쪽에 접근시

            if (checkRange(current.Top, target.Bottom, dockGap) && checkXLine(target))

            {

                current.Top = target.Bottom;

            }

 

            // 도킹 대상 폼윈도우의 위쪽에 접근시

            if (checkRange(current.Bottom, target.Top, dockGap) && checkXLine(target))

            {

                current.Top = target.Top - current.Height;

            }

        }

 

        // 대상 폼과 도킹되어 있는가

        private bool isDocked(Form target)

        {

            return (target.Left == prevLoc.X + current.Width ||

                    target.Right == prevLoc.X ||

                    target.Top == prevLoc.Y + current.Height ||

                    target.Bottom == prevLoc.Y);

        }

 

        // 대상 폼 윈도우 테두리의 범위안으로 이동했는가

        private bool checkRange(int curVal, int tarVal, int range)

        {

            return (curVal > tarVal - range) && (curVal < tarVal + range);

        }

 

        // 대상 폼 윈도우와 수평선상에 있는가

        private bool checkXLine(Form target)

        {

            return (current.Left < target.Right) && (current.Right > target.Left);

        }

 

        // 대상 폼 윈도우와 수직선상에 있는가

        private bool checkYLine(Form target)

        {

            return (current.Top < target.Bottom) && (current.Bottom > target.Top);

        }        

    }

}

 


 

 

사용하기

위의 객체를 만들고서 도킹을 하고 싶은 대상 폼 윈도우를 지정해주면 됩니다. 

그리고 도킹 범위를 지정할 수 있습니다.

private void Form1_Move(object sender, EventArgs e)

{

formutil.docking(child, 10);

}


 

private void Form2_Move(object sender, EventArgs e)

{

formUtil.docking(this.Owner, 10);

}


 

 

(참고)메인 폼 윈도우가 다른 폼 윈도우를 소유하기

AddOwnedForm(targetForm);

위의 메서드를 사용합니다.

메인 폼 윈도우에서는 OwnedForms 으로 소유한 폼들을 관리하고

대상 폼 윈도우에서는 Owner 으로 메인 폼 윈도우에 접근할 수 있습니다.


 

전체 소스는 파일 첨부 했습니다.

반응형

+ Recent posts