맨날맑음 님께서 제공해주신 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 으로 메인 폼 윈도우에 접근할 수 있습니다.
전체 소스는 파일 첨부 했습니다.
'Program > C#' 카테고리의 다른 글
Silent Install of MS .Net Framework Version 2 (0) | 2010.02.05 |
---|---|
텍스트박스에 워터 마크 추가(배경) (0) | 2010.01.26 |
윈폼 파일 드레그하기 (0) | 2010.01.26 |
C# 초보자분들을 위한 기초강좌 (0) | 2010.01.24 |
WMI 를 활용한 원격(로컬)서버 CPU사용량 실시간 모니터링하기 (0) | 2010.01.21 |