Saturday, December 21, 2013

드래그앤드롭을 처리할 때는 적절한 threshold를 주는 게 수명 연장에 좋습니다

본론에 들어가기에 앞서,
일반적인 상황-윈도우(컨트롤)가 하나-이라면 이런 문제는 생기지 않는다.
(그래서 지난 번 프로그램에서는 이런 문제가 없었던 거고.)

이번엔 클릭을 인식하는 객체를 모두 컨트롤(Control)로 만들었다. 그랬더니 특이한 결과가 나와서 짜증났왔다.

즉, 이번에는 Movable이라는 클래스를 Control로부터 상속받아 드래그앤드롭을 지원하게 하였다. 여기에 MovableTest를 다시 상속하여 실제 테스트 프로그램에서 사용하였다.

public class Movable : Control {
    override void OnMouseDown(MouseEventArgs e) {...}
    override void OnMouseUp(MouseEventArgs e) {...}
    override void OnMouseMove(MouseEventArgs e) {...}
    override void OnMouseHover(EventArgs e){...}
}

public class MovableTest : Movable {
    override void OnMouseUp(MouseEventArgs e) {
        if(!dragging) { MessageBox.Show("clicked"); }
    }
}

Form1() {
    var mt1 = new MovableTest(new Point(100, 100), new Size(150, 150));
    var mt2 = new MovableTest(new Point(400, 400), new Size(75, 75));
    ...
}

이런 식으로 만드는 것이다.

다른 건 잘 됐는데, 한 컨트롤을 만지다가 다른 컨트롤을 처음으로 클릭하면(very first click이라고 해야 되나, 그러니까 mt1을 드래그하거나, 클릭하거나 하다가 mt2를 클릭하면) 클릭된 효과가 안 나는 것이다(clicked 메시지박스가 안 뜸).

이벤트핸들러를 추가해서 내부 변수들을 추적하는 등의 삽질을 한 끝에...
컨트롤 사이를 전환할 때 클릭만 해도 OnMouseMove가 trigger되는 황당한 현상을 발견했다.
마우스 클릭하다 손 떨리고 그런 거 아니다(이전 프로그램에서는 threshold 따위 없이 살짝이라도 움직이면 드래그로 판정해버렸기 때문에 내 손이 문제인 건 아니다(...)).

결국 OnMouseMove에서 드래깅 여부를 판별할 때 적당한 threshold를 주어 그 값 이상일 때만 dragging으로 인정함으로써 해결하였다.

Control의 특성이라고 생각하고 넘어가기로 한다.


짜증짜증짜증

No comments:

Post a Comment

창 핸들을 만드는 동안 오류가 발생했습니다

System.ComponentModel.Win32Exception was unhandled   MyForm w = new MyForm IntPtr handle = wnd.Handle;   // Exception occurs here class MyFo...