void StartDragging() { try { using (ModelEditingScope editingScope = this.ModelItem.BeginEdit(SR.MoveEditingScopeDescription, true)) { HashSet <WorkflowViewElement> draggedViews = new HashSet <WorkflowViewElement>(); Dictionary <ModelItem, ICompositeView> sourceContainers = new Dictionary <ModelItem, ICompositeView>(); HashSet <ICompositeView> compViewSet = new HashSet <ICompositeView>(); Selection selection = this.Context.Items.GetValue <Selection>(); IEnumerable <ModelItem> selectedObjects = selection.SelectedObjects; IEnumerable <ModelItem> modelItemsToDrag = DragDropHelper.GetModelItemsToDrag(selectedObjects); // Save the source containers for the dragged items foreach (ModelItem modelItem in modelItemsToDrag) { WorkflowViewElement view = (WorkflowViewElement)modelItem.View; draggedViews.Add(view); ICompositeView container = DragDropHelper.GetCompositeView(view) as ICompositeView; sourceContainers.Add(modelItem, container); // If Add returns true => the container is added the first time, which is always ok // If Add returns false => the container is added more than once // it must be a IMultipleDragEnabledCompositeView, otherwise, return, because // we don't support dragging from ICompositeView. if (!compViewSet.Add(container) && !(container is IMultipleDragEnabledCompositeView)) { return; } } // Calculate the anchor point for the dragged items Point relativeLocation = GetRelativeLocation(draggedViews); Point referencePoint = this.lastMouseDownPoint; referencePoint.Offset(relativeLocation.X, relativeLocation.Y); DataObject dataObject = DragDropHelper.DoDragMoveImpl(draggedViews, referencePoint); IEnumerable <WorkflowViewElement> movedViewElements = DragDropHelper.GetDragDropMovedViewElements(dataObject); // once drag drop is done make sure the CompositeView is notified of the change in data if (movedViewElements != null) { Dictionary <ICompositeView, List <ModelItem> > containerMovedModelItemList = new Dictionary <ICompositeView, List <ModelItem> >(); // Create containerMovedModelItemList foreach (WorkflowViewElement view in movedViewElements) { ICompositeView compView = DragDropHelper.GetCompositeView(view) as ICompositeView; Fx.Assert(compView != null, "not an ICompositeView"); if (!containerMovedModelItemList.ContainsKey(compView)) { containerMovedModelItemList.Add(compView, new List <ModelItem>()); } containerMovedModelItemList[compView].Add(view.ModelItem); } // Call OnItemsMoved to notify the source container. foreach (KeyValuePair <ICompositeView, List <ModelItem> > pair in containerMovedModelItemList) { if (pair.Key is IMultipleDragEnabledCompositeView) { ((IMultipleDragEnabledCompositeView)pair.Key).OnItemsMoved(pair.Value); } else { if (pair.Value.Count >= 2) { throw FxTrace.Exception.AsError( new InvalidOperationException(SR.Error_MovingMoreThanOneItemsFromICompositeView)); } pair.Key.OnItemMoved(pair.Value[0]); } } // animation foreach (WorkflowViewElement view in movedViewElements) { BeginDropAnimation(view); } } // the drop target is using old DragDropHelper API and did not set the moved view elements else { DragDropEffects executedDragDropEffect = DragDropHelper.GetDragDropCompletedEffects(dataObject); if (executedDragDropEffect == DragDropEffects.Move) { if (modelItemsToDrag.Count() == 1) { ModelItem movedItem = modelItemsToDrag.First <ModelItem>(); sourceContainers[movedItem].OnItemMoved(movedItem); BeginDropAnimation((WorkflowViewElement)movedItem.View); } else { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.DraggingMulitpleItemsError)); } } } editingScope.Complete(); bool dropHappened = movedViewElements != null || DragDropHelper.GetDragDropCompletedEffects(dataObject) == DragDropEffects.Move; if (dropHappened) { // add the selected objects back into selection. this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() => { foreach (ModelItem item in selectedObjects) { // We need only the first one IInputElement viewToFocus = item == null ? null : item.View as IInputElement; if (viewToFocus != null) { Keyboard.Focus(viewToFocus); break; } } this.Context.Items.SetValue(new Selection(selectedObjects)); })); } } } catch (Exception e) { ErrorReporting.ShowErrorMessage(e.Message); } }