Window/WPF2009. 9. 27. 20:41

프로그램 작성 중 Drag 기능을 사용해야 할 때가 있습니다.

일반적으로 Window는 DragMove라는 함수를 호출하여 사용할 수 있지만

나머지는 구현을 하여야 하는 일이 생깁니다.

 

TranslateTransformDependencyProperty   이용한 간단한 예제를 만들어 보았습니다.

 

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
Posted by 열ㅇl