2011-06-28 12 views
6

Hace poco hice una pregunta sobre cómo reordenar un ItemsControl usando Arrastrar y soltar (ItemsControl Drag and Drop). La respuesta funcionó muy bien por el momento (código a continuación), pero ahora estoy tratando de implementar MVVM y la solución actual requiere acceso a los elementos en la vista. ¿Alguna idea de cómo cambiar esto para trabajar con MVVM? Tengo la intención de hacer que las propiedades asociadas a unirse a los comandos, pero no sé cómo deshacerse de las líneas tales como: int index = (int)(e.GetPosition(DimsContainer).X/width);Reordenar ItemsControl con Arrastrar y soltar usando MVVM

actual código de arrastrar y soltar:

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 }); 
       } 
      } 
     } 
    } 

Respuesta

6

uso de arrastrar y soltar comportamiento. p.ej. http://www.codeproject.com/KB/WPF/gong-wpf-dragdrop-ii.aspx

+0

Eso no responde mi pregunta. Mi problema es que tengo que arrastrar y soltar en el MISMO contenedor y no sé cómo deshacerme de la dependencia de la vista (como en la línea: int index = (int) (e.GetPosition (DimsContainer)) .X/ancho);) – KrisTrip

+0

has revisado el artículo anterior, permite arrastrar y soltar en el MISMO contenedor. Los comportamientos son la única buena forma de implementar arrastrar y soltar con MVVM – user819313

+0

Marcando esto como el b/c correcto que ayudó con MVVM. Para deshacerme de la línea que hacía referencia a DimsContainer, utilicé el parámetro del remitente en su lugar y lo fundí como ItemsControl. – KrisTrip