I recently asked a question about how to reorder ItemsControl using Drag and Drop ( ItemsControl Drag and Drop ). At the moment, the answer works fine (code below), but now I'm trying to implement MVVM, and the current solution requires access to the elements in the view. Any ideas how to change this to work with MVVM? I plan to attach attached properties to commands, but I donβt know how to get rid of strings like: int index = (int)(e.GetPosition(DimsContainer).X / width);
Current drag and drop code:
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 }); } } } }
source share