Silverlight에서 컨트롤을 드래그 하는 방법을 알아보자!
얼마전에 컨트롤을 드래그 하는것을 만들다가 Silverlight의 좌표 체계(?)인
Margin 방식이 좀 낯설어서 생각보다 오래 테스트를 하여 구현 했기 때문에
드래그하는 방법을 차근차근 알아보려한다. 

구현할 프로그램

 Grid 안에 담긴 컨트롤을 마우스로 드래그 되야함.
   유의사항
       드래그 될때 마우스로 잡은 곳이 변경 되어서는 안되며! 빠르게 움직여도  컨트롤을 놓쳐서는 안된다!

프로젝트 생성 (MyDrag)



Microsoft Expression Blend툴을 이용한 간단한 컨트롤 디자인

간단한 메모 기능이 있는 웹젯같은 형태로 만들기 위해 TextBox를 배치햇고 상단에는 Drag를 위한
DragPanel이라는 Grid 배치
여기서 컨트롤의 Margin의 right botton 부분을 0으로 고정한다;

 
비하인드 코드( page.xaml.cs)로 가서 DragPanel의 마우스 이벤트를 등록한다
Class의 멤버 변수로 이전 마우스의 좌표를 저장하기 위한 Point beforePositon; 변수를 선언한다

Point beforePositon;

void DragPanel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
            DragPanel.MouseMove -= new MouseEventHandler(DragPanel_MouseMove);
}

void DragPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
            DragPanel.MouseMove += new MouseEventHandler(DragPanel_MouseMove);
}

void DragPanel_MouseMove(object sender, MouseEventArgs e)
{
           
}


여기서 MouseLeftButtonDown이벤트 발생후에만 Drag를 할수있으므로 MouseLeftButtonDown이벤트 처리기에
DragPanel.MouseMove += new MouseEventHandler(DragPanel_MouseMove);
이벤트를 등록하고 MouseLeftButtonUp 이벤트 처리기에서 마우스 Move 이벤트를 해지한다!


이제 마우스 MouseLeftButtonUp 이벤트 처리기부터 차근차근 코딩 해보자;
일단 마우스가 클릭되면 컨트롤 밖으로 마우스가 벗어나더라도 마우스 이벤트를 받을수 있어야
빠르게 드레그해도 드레그가 되기 때문에 DragPanel.CaptureMouse(); 를 호출한다

드레그를 시작한 마우스 좌표를 저장하기 위해 미리 선언해둔 beforePosition 변수에 현재 좌표를 저장한다
beforePositon = e.GetPosition(LayoutRoot);
void DragPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
            DragPanel.CaptureMouse();
            beforePositon = e.GetPosition(LayoutRoot);
            DragPanel.MouseMove += new MouseEventHandler(DragPanel_MouseMove);
}

MouseMove 이벤트 처리기에서 실질적인 Drag를 처리한다;
우선 마우스의 좌표가 변화를 구하여 beforePositon 변수에 저장한다;
beforePositon.X = e.GetPosition(LayoutRoot).X - beforePositon.X;
beforePositon.Y = e.GetPosition(LayoutRoot).Y - beforePositon.Y;

현재 컨트롤의 Margin정보를 temp 객체에 저장하고
위에서 구한 차이만큼을 가감한다; 이때 Right 와 Botton은 위에서 0으로 고정했으므로 신경 쓸 필요가 없다

변경된 Margin을 컨트롤에 적용한다;
this.Margin = temp;

 다음 드레그를 위해 현재 위치를 저장한다
 beforePositon = e.GetPosition(LayoutRoot);
void DragPanel_MouseMove(object sender, MouseEventArgs e)
{
            beforePositon.X = e.GetPosition(LayoutRoot).X - beforePositon.X;
            beforePositon.Y = e.GetPosition(LayoutRoot).Y - beforePositon.Y;
            Thickness temp = this.Margin;
            temp.Left += beforePositon.X;
            temp.Top += beforePositon.Y;
            this.Margin = temp;
            beforePositon = e.GetPosition(LayoutRoot);
}

MouseLeftButtonUp 이벤트 처리기에서는 CaptureMouse를 ReleaseMouseCapture 해준다
void DragPanel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
            DragPanel.ReleaseMouseCapture();
            DragPanel.MouseMove -= new MouseEventHandler(DragPanel_MouseMove);
}

이렇게만 해주면 마우스 드레그가 아주 잘되는 것을 확인 할 수 있다!
Posted by 맨날맑음
,