프로그램 작성 중 Drag 기능을 사용해야 할 때가 있습니다.
일반적으로 Window는 DragMove라는 함수를 호출하여 사용할 수 있지만
나머지는 구현을 하여야 하는 일이 생깁니다.
TranslateTransform과 DependencyProperty 을 이용한 간단한 예제를 만들어 보았습니다.
TranslateTransform은 RenderTransform의 현재 오프셋을 변경시킬 수가 있습니다.
DependencyProperty (의존 속성)클래스 를 이용하면 여러 객체에 대해 기능을 부여 할 수 있습니다.
의존 속성의 값을 변경하면 자동적으로 객체를 변경 시킬 수가 있습니다..
선언은 다음과 같습니다.
15 private static readonly DependencyProperty DragProperty =
16 DependencyProperty.RegisterAttached("Drag", 17 typeof(bool), 18 typeof(Drag), 19 new UIPropertyMetadata(false, ChangeDragProperty)); |
4개의 파라미터는 다음과 같습니다.
Name | 등록 속성의 이름 |
Property type | 속성 타입 |
Owner type | 부모 타입 |
Type metadata | 메타데이터 지정 |
UIPropertyMetadata
코어 수준에서 렌더링/사용자 인터페이스에 영향을 주는 프레임워크가 아닌 속성에 대해 속성 메타데이터를 제공합니다.
defaultValue | 속성의 기본값, 일반적으로 특정 형식의 값으로 제공. |
propertyChangedCallback | 속성의 유효 값이 변경될 때마다 호출되는 함수 |
[ 함수 내용 ]
- 프로퍼티 값 변경 시 이벤트 설정을 변경합니다.
39 private static void ChangeDragProperty(DependencyObject d, DependencyPropertyChangedEventArgs e)
40 { 41 FrameworkElement element = d as FrameworkElement; 42 43 if (element != null) 44 { 45 if ((bool)e.NewValue) 46 { 47 // 오프셋 변경을 위해 생성합니다. 48 element.RenderTransform = new TranslateTransform(0, 0); 49 50 element.PreviewMouseDown += element_PreviewMouseDown; 51 element.PreviewMouseUp += element_PreviewMouseUp; 52 } 53 else 54 { 55 element.PreviewMouseDown -= element_PreviewMouseDown; 56 element.PreviewMouseUp -= element_PreviewMouseUp; 57 } 58 } 59 } |
- 드래그 시 객체를 놓치지 않기 위해 윈도우의 MouseMove를 사용했습니다.
간단한 방법으로 객체 내의 처음 포인터 값과 현재 포인터 값의 차이만큼 오프셋을 변경합니다.
ZIndex를 변경하여 선택한 객체를 상위로 올립니다.
61 static void window_PreviewMouseMove(object sender, MouseEventArgs e) 62 { 63 if (CurrentElement != null && 64 e.LeftButton == MouseButtonState.Pressed || e.RightButton == MouseButtonState.Pressed) 65 { 66 Point CurrentPoint = e.GetPosition(CurrentElement); 67 68 TranslateTransform Translate = CurrentElement.RenderTransform as TranslateTransform; 69 70 if (Translate != null) 71 { 72 CurrentElement.LayoutTransform = Translate; 73 Translate.X += CurrentPoint.X - FirstPoint.X; 74 Translate.Y += CurrentPoint.Y - FirstPoint.Y; 75 } 76 } 77 } 78 79 static void element_PreviewMouseDown(object sender, MouseButtonEventArgs e) 80 { 81 CurrentElement = sender as FrameworkElement; 82 83 OldzIndex = Canvas.GetZIndex(CurrentElement); 84 Canvas.SetZIndex(CurrentElement, 100); 85 86 FirstPoint = e.GetPosition(CurrentElement); 87 88 window.PreviewMouseMove += window_PreviewMouseMove; 89 } 90 91 private static void element_PreviewMouseUp(object sender, MouseButtonEventArgs e) 92 { 93 FrameworkElement element = sender as FrameworkElement; 94 95 Canvas.SetZIndex(element, OldzIndex); 96 97 CurrentElement = window; 98 window.MouseMove -= window_PreviewMouseMove; 99 } |
- 다음과 같이 사용하면 됩니다.
Drag.SetWindow(this);
Drag.SetDrag(sample_btn, true); Drag.SetDrag(sample_image1, true); Drag.SetDrag(sample_image2, true); Drag.SetDrag(sample_text, true); Drag.SetDrag(title, true); |
[ 시연 영상 ]
'Window > WPF' 카테고리의 다른 글
[ WPF ] Window 사이즈 변경 시 컨트롤 크기 변경하기 (3) | 2010.02.08 |
---|---|
[WPF] Object Capture (0) | 2010.01.29 |
[WPF] 시계 만들기 (0) | 2010.01.26 |
[WPF] Image Pixel (0) | 2010.01.24 |
[WPF] Drag, Scale, Rotate (1) | 2010.01.24 |