출처 : http://social.msdn.microsoft.com/Forums/en/wpf/thread/d32bb0af-b14f-4e88-ad36-098d11cd375c

 

WPF의 StackPanel 컨트롤에 들어있는 아이템들에 Drag and Drop 기능을 입혀 보겠습니다.

 

1. StackPanel을 만들고 AllowDrop 속성 및 마우스 이벤트를 등록 합니다.
   테스트를 위해 TextBlock 아이템을 넣어 놓았습니다.

<StackPanel x:Name="Container" Orientation="Vertical"
                            HorizontalAlignment="Stretch"
                                AllowDrop="True"
                                PreviewMouseLeftButtonDown="Container_PreviewMouseLeftButtonDown"
                                PreviewMouseLeftButtonUp="Container_PreviewMouseLeftButtonUp"
                                PreviewMouseMove="Container_PreviewMouseMove"
                                Drop="Container_Drop">
           
            <TextBlock Text="1번" FontSize="20" HorizontalAlignment="Stretch" TextAlignment="Center" Background="Red"/>
            <TextBlock Text="2번" FontSize="20" HorizontalAlignment="Stretch" TextAlignment="Center" Background="Blue"/>
            <TextBlock Text="3번" FontSize="20" HorizontalAlignment="Stretch" TextAlignment="Center" Background="Yellow"/>
            <TextBlock Text="4번" FontSize="20" HorizontalAlignment="Stretch" TextAlignment="Center" Background="Beige"/>
           
        </StackPanel>

 

 

2. Behind Code에 추가된 이벤트 함수에 Drag and Drop에 필요한 변수를 등록 합니다.

 

        private bool _isDown;  // 마우스 클릭 체크
        private bool _isDragging; // 컨트롤을 드레깅 하는지 체크
        private Point _startPoint; // Drag 하는 아이템의 시작 위치
        private UIElement _realDragSource; 
        private UIElement _dummyDragSource = new UIElement();

 

3. 마우스를 클릭 했을때 StackPanel 안에 있는 자식 컨트롤을 선택 하는지 체크 하는 코드를 입력 합니다.

 

        private void Container_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.Source == this.Container)
            {
            }
            else
            {
                _isDown = true;
                _startPoint = e.GetPosition(this.Container);
            }
        }

 

4. 마우스를 땠을때 변수를 초기화 시켜 주는 코드를 입력 합니다.

        private void Container_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _isDown = false;
            _isDragging = false;
            if (_realDragSource != null)
            {
                _realDragSource.ReleaseMouseCapture();
            }
        }

 

5. 컨트롤을 드레깅 하는동안 위치를 확인 하는 코드를 입력 합니다.

        private void Container_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (_isDown)
            {
                if ((_isDragging == false) && ((Math.Abs(e.GetPosition(this.Container).X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance) ||
                    (Math.Abs(e.GetPosition(this.Container).Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)))
                {
                    _isDragging = true;
                    _realDragSource = e.Source as UIElement;
                    _realDragSource.CaptureMouse();
                    DragDrop.DoDragDrop(_dummyDragSource, new DataObject("UIElement", e.Source, true), DragDropEffects.Move);
                }
            }
        }

 

6. 컨트롤을 Drop 시켰을때 컨트롤들의 순서를 바꿔주는 코드를 입력합니다.

         private void Container_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("UIElement"))
            {
                UIElement droptarget = e.Source as UIElement;
                int droptargetIndex = -1, i = 0;

 

                foreach (UIElement element in this.Container.Children)
                {
                    if (element.Equals(droptarget))
                    {
                        droptargetIndex = i;
                        break;
                    }
                    i++;
                }
                if (droptargetIndex != -1)
                {
                    this.Container.Children.Remove(_realDragSource);
                    this.Container.Children.Insert(droptargetIndex, _realDragSource);
                }

 

                _isDown = false;
                _isDragging = false;
                _realDragSource.ReleaseMouseCapture();
            }
        }

 

샘플 다운로드 :StackPanelDragAndDrop.zip

 

+ Recent posts