2011-06-28 16 views
6

最近ドラッグアンドドロップ(ItemsControl Drag and Drop)を使用してItemsControlを並べ替える方法に関する質問がありました。答えは当分の間は素晴らしい(下のコード)でしたが、今はMVVMを実装しようとしており、現在のソリューションではビュー内の項目にアクセスする必要があります。任意のアイデアMVVMで動作するようにこれを変更する方法?私は、コマンドにバインドする添付プロパティを作成する予定が、私は、次のような行を取り除く方法がわからない:int index = (int)(e.GetPosition(DimsContainer).X/width);Reorder Items MVVMを使用したドラッグアンドドロップによるコントロール

現在のドラッグアンドドロップコード:

private void DimsContainer_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     _isDown = true; 
     _startPoint = e.GetPosition(this.DimsContainer); 
    } 

    private void DimsContainer_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     _isDown = false; 
     _isDragging = false; 

     if (_realDragSource != null) 
     { 
      _realDragSource.ReleaseMouseCapture(); 
     } 
    } 

    private void DimsContainer_PreviewMouseMove(object sender, MouseEventArgs e) 
    { 
     if (_isDown) 
     { 
      if ((_isDragging == false) && 
       ((Math.Abs(e.GetPosition(this.DimsContainer).X - _startPoint.X) > 
        SystemParameters.MinimumHorizontalDragDistance) || 
       (Math.Abs(e.GetPosition(this.DimsContainer).Y - _startPoint.Y) > 
        SystemParameters.MinimumVerticalDragDistance))) 
      { 
       _isDragging = true; 
       _realDragSource = e.Source as UIElement; 
       _realDragSource.CaptureMouse(); 

       double width = ((FrameworkElement)(this.DimsContainer.ItemContainerGenerator.ContainerFromIndex(0))).ActualWidth; 
       int index = (int)(e.GetPosition(DimsContainer).X/width); 
       DragDrop.DoDragDrop(_realDragSource, new DataObject("UIElement", index, true), DragDropEffects.Move); 
      } 
     } 
    } 

    private void DimsContainer_DragEnter(object sender, DragEventArgs e) 
    { 
     if (e.Data.GetDataPresent("UIElement")) 
     { 
      e.Effects = DragDropEffects.Move; 
     } 
    } 

    private void DimsContainer_Drop(object sender, DragEventArgs e) 
    { 
     if (e.Data.GetDataPresent("UIElement")) 
     { 
      int sourceIndex = (int)e.Data.GetData("UIElement"); 
      int removedObject = this.indices[sourceIndex]; 
      this.indices.RemoveAt(sourceIndex); 

      UIElement droptarget = e.Source as UIElement; 

      // If a drag/drop is happening, there is definitely 
      // one child in the DimsContainer 
      double width = ((FrameworkElement)(this.DimsContainer.ItemContainerGenerator.ContainerFromIndex(0))).ActualWidth; 
      int index = (int)(e.GetPosition(DimsContainer).X/width); 

      try 
      { 
       this.indices.Insert(index, removedObject); 
      } 
      catch (InvalidOperationException) 
      { 
       // ignore 
      } 

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

    public static int RemoveItemFromItemsControl(ItemsControl itemsControl, object itemToRemove) 
    { 
     int indexToBeRemoved = -1; 
     if (itemToRemove != null) 
     { 
      indexToBeRemoved = itemsControl.Items.IndexOf(itemToRemove); 

      if (indexToBeRemoved != -1) 
      { 
       IEnumerable itemsSource = itemsControl.ItemsSource; 
       if (itemsSource == null) 
       { 
        itemsControl.Items.RemoveAt(indexToBeRemoved); 
       } 
       // Is the ItemsSource IList or IList<T>? If so, remove the item from the list. 
       else if (itemsSource is IList) 
       { 
        ((IList)itemsSource).RemoveAt(indexToBeRemoved); 
       } 
       else 
       { 
        Type type = itemsSource.GetType(); 
        Type genericIListType = type.GetInterface("IList`1"); 
        if (genericIListType != null) 
        { 
         type.GetMethod("RemoveAt").Invoke(itemsSource, new object[] { indexToBeRemoved }); 
        } 
       } 
      } 
     } 
     return indexToBeRemoved; 
    } 

    public static void InsertItemInItemsControl(ItemsControl itemsControl, object itemToInsert, int insertionIndex) 
    { 
     if (itemToInsert != null) 
     { 
      IEnumerable itemsSource = itemsControl.ItemsSource; 

      if (itemsSource == null) 
      { 
       itemsControl.Items.Insert(insertionIndex, itemToInsert); 
      } 
      // Is the ItemsSource IList or IList<T>? If so, insert the dragged item in the list. 
      else if (itemsSource is IList) 
      { 
       ((IList)itemsSource).Insert(insertionIndex, itemToInsert); 
      } 
      else 
      { 
       Type type = itemsSource.GetType(); 
       Type genericIListType = type.GetInterface("IList`1"); 
       if (genericIListType != null) 
       { 
        type.GetMethod("Insert").Invoke(itemsSource, new object[] { insertionIndex, itemToInsert }); 
       } 
      } 
     } 
    } 

答えて

6

利用のドラッグ&ドロップ動作。例えばhttp://www.codeproject.com/KB/WPF/gong-wpf-dragdrop-ii.aspx

+0

私の質問には答えません。私の問題は、SAMEコンテナをドラッグ&ドロップする必要があることです。ビューの依存関係を取り除く方法はわかりません(int index =(int)(e.GetPosition(DimsContainer ).X/width);) – KrisTrip

+0

上記の記事をチェックして、それをドラッグして同じコンテナにドロップすることができます。ビヘイビアは、MVVMでドラッグアンドドロップを実装する唯一の良い方法です – user819313

+0

これはMVVMで役立つ正しいb/cとマークします。 DimsContainerを参照している行を取り除くために、代わりにsenderパラメータを使用し、ItemsControlとしてキャストしました。 – KrisTrip

関連する問題