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