public static void OnAddAnnotationCommandExecuted(ExecutedRoutedEventArgs e, ModelItem modelItem) { ModelProperty property = modelItem.Properties.Find(Annotation.AnnotationTextPropertyName); if (property != null) { using (ModelEditingScope editingScope = modelItem.BeginEdit(SR.AddAnnotationDescription)) { property.SetValue(string.Empty); ViewStateService viewStateService = modelItem.GetEditingContext().Services.GetService <ViewStateService>(); viewStateService.StoreViewStateWithUndo(modelItem, Annotation.IsAnnotationDockedViewStateName, false); editingScope.Complete(); } if (modelItem.View != null) { WorkflowViewElement element = modelItem.View as WorkflowViewElement; if (element != null) { element.OnEditAnnotation(); } } } e.Handled = true; }
//Calculates whether ShowExpanded for a given WorklfowViewElement should be true or false. public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { ModelItem modelItem = (ModelItem)values[0]; bool isRootDesigner = (bool)values[1]; bool shouldExpandAll = (bool)values[2]; bool shouldCollapseAll = (bool)values[3]; bool expandState = (bool)values[4]; bool pinState = (bool)values[5]; WorkflowViewElement viewElement = (WorkflowViewElement)values[6]; //Pinstate should be false in following cases (Designer should be unpinned in following cases): //1. ExpandAll is not enabled. //2. ExpandAll is enabled and ExpandState is true. //Similarly for Collapse All. if ((!shouldExpandAll || expandState) && (!shouldCollapseAll || !expandState)) { viewElement.PinState = false; } if (viewElement.IsAncestorOfRootDesigner) { return(true); } return(ViewUtilities.ShouldShowExpanded(isRootDesigner, viewElement.DoesParentAlwaysExpandChild(), viewElement.DoesParentAlwaysCollapseChildren(), expandState, shouldExpandAll, shouldCollapseAll, viewElement.PinState)); }
protected override void OnDrop(DragEventArgs e) { int index = addAtEndMarker; WorkflowViewElement dropTarget = null; if (e.OriginalSource is WorkflowViewElement) { dropTarget = (WorkflowViewElement)e.OriginalSource; } else { dropTarget = VisualTreeUtils.FindFocusableParent <WorkflowViewElement>((UIElement)e.OriginalSource); } if (null != dropTarget && null != dropTarget.ModelItem) { int targetIndex = this.Items.IndexOf(dropTarget.ModelItem); if (-1 != targetIndex) { index = targetIndex + 1; } } OnItemsDropped(e, index); base.OnDrop(e); }
internal static DataObject DoDragMoveImpl(IEnumerable <WorkflowViewElement> draggedViewElements, Point referencePoint) { List <ModelItem> draggedModelItems = new List <ModelItem>(); bool first = true; WorkflowViewElement viewElement = null; foreach (WorkflowViewElement view in draggedViewElements) { if (view != null) { if (first) { viewElement = view; first = false; } draggedModelItems.Add(view.ModelItem); view.IsHitTestVisible = false; } } DataObject dataObject = new DataObject(ModelItemsDataFormat, draggedModelItems); // For compatiblity if (viewElement != null) { dataObject.SetData(ModelItemDataFormat, viewElement.ModelItem); dataObject.SetData(CompositeViewFormat, GetCompositeView(viewElement)); } dataObject.SetData(DragAnchorPointFormat, referencePoint); if (viewElement != null) { DesignerView designerView = viewElement.Context.Services.GetService <DesignerView>(); ViewElementDragShadow dragShadow = new ViewElementDragShadow(designerView.scrollableContent, draggedViewElements, referencePoint, designerView.ZoomFactor); designerView.BeginDragShadowTracking(dragShadow); //whenever drag drop fails - ensure getting rid of drag shadow try { DragDrop.DoDragDrop(designerView, dataObject, DragDropEffects.Move | DragDropEffects.Copy | DragDropEffects.Scroll | DragDropEffects.Link); } catch { //let the caller handle exception throw; } finally { designerView.EndDragShadowTracking(dragShadow); foreach (WorkflowViewElement view in draggedViewElements) { if (view != null) { view.IsHitTestVisible = true; } } } } return(dataObject); }
public static UIElement GetCompositeView(WorkflowViewElement workflowViewElement) { if (workflowViewElement == null) { throw FxTrace.Exception.ArgumentNull("workflowViewElement"); } return((UIElement)workflowViewElement.GetValue(DragDropHelper.DragSourceProperty)); }
//This enables us to get children ICompositeViews from WorkflowViewElements. //Eg. get the WorkflowItemsPresenter from SequenceDesigner. //This is useful for Cut-Copy-Paste, Delete handling, etc. internal static void RegisterWithParentViewElement(ICompositeView container) { WorkflowViewElement parent = GetParentViewElement(container); if (parent != null) { CutCopyPasteHelper.AddChildContainer(parent, container); } }
public static void Delete(EditingContext context) { if (context == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("context")); } Selection selection = context.Items.GetValue <Selection>(); if (null != selection) { bool selectRoot = false; DesignerView designerView = context.Services.GetService <DesignerView>(); var toDelete = selection.SelectedObjects.Where(p => null != p.View && p.View is WorkflowViewElement && !p.View.Equals(designerView.RootDesigner)); if (toDelete.Count() > 0) { using (EditingScope es = (EditingScope)toDelete.FirstOrDefault().BeginEdit(SR.DeleteOperationEditingScopeDescription)) { Dictionary <ICompositeView, List <ModelItem> > containerToModelItemsDict = new Dictionary <ICompositeView, List <ModelItem> >(); List <ModelItem> modelItemsPerContainer; foreach (var item in toDelete) { ICompositeView container = (ICompositeView)DragDropHelper.GetCompositeView((WorkflowViewElement)item.View); if (null != container) { if (!containerToModelItemsDict.TryGetValue(container, out modelItemsPerContainer)) { modelItemsPerContainer = new List <ModelItem>(); containerToModelItemsDict.Add(container, modelItemsPerContainer); } modelItemsPerContainer.Add(item); } } foreach (ICompositeView container in containerToModelItemsDict.Keys) { container.OnItemsDelete(containerToModelItemsDict[container]); selectRoot = true; } if (selectRoot) { DesignerView view = context.Services.GetService <DesignerView>(); if (null != view) { WorkflowViewElement rootView = view.RootDesigner as WorkflowViewElement; if (rootView != null) { Selection.SelectOnly(context, rootView.ModelItem); } } } es.Complete(); } } } }
static ICompositeView GetContainerForPaste(ModelItem pasteModelItem, Point clickPoint) { ICompositeView pasteContainer = null; if (null != pasteModelItem && null != pasteModelItem.View && pasteModelItem.View is WorkflowViewElement) { pasteContainer = ((WorkflowViewElement)pasteModelItem.View).ActiveCompositeView; } if (null == pasteContainer) { //Get clicked container. if (clickPoint.X > 0 && clickPoint.Y > 0) { pasteContainer = GetClickedContainer(pasteModelItem, clickPoint); } //If the container itself is a WVE, there's posibility that it's collapsed. //Thus, we need to check this as well. if (pasteContainer != null && pasteContainer is WorkflowViewElement) { WorkflowViewElement view = pasteContainer as WorkflowViewElement; if (!view.ShowExpanded) { pasteContainer = null; } } else if (pasteContainer == null) //If the modelitem.View itself is a container. { WorkflowViewElement view = pasteModelItem.View as WorkflowViewElement; if (view != null && view.ShowExpanded) { pasteContainer = pasteModelItem.View as ICompositeView; } } //Get the container registered with modelItem.View if unambigous //If nothing works take the container with keyboard focus if one exists. if (pasteContainer == null) { HashSet <ICompositeView> childrenContainers = CutCopyPasteHelper.GetChildContainers(pasteModelItem.View as WorkflowViewElement); if ((childrenContainers == null || childrenContainers.Count == 0) && null != pasteModelItem.View) { pasteContainer = (ICompositeView)DragDropHelper.GetCompositeView((WorkflowViewElement)pasteModelItem.View); } else if (null != childrenContainers && childrenContainers.Count == 1) { pasteContainer = new List <ICompositeView>(childrenContainers)[0]; } else { pasteContainer = Keyboard.FocusedElement as ICompositeView; } } } return(pasteContainer); }
static HashSet <ICompositeView> GetChildContainers(WorkflowViewElement workflowViewElement) { HashSet <ICompositeView> childContainers = null; if (workflowViewElement != null && workflowViewElement.ShowExpanded) { childContainers = (HashSet <ICompositeView>)workflowViewElement.GetValue(CutCopyPasteHelper.ChildContainersProperty); } return(childContainers); }
public static void OnEditAnnotationCommandExecuted(ExecutedRoutedEventArgs e, ModelItem modelItem) { WorkflowViewElement element = modelItem.View as WorkflowViewElement; if (element != null) { element.OnEditAnnotation(); } e.Handled = true; }
public static void SetCompositeView(WorkflowViewElement workflowViewElement, UIElement dragSource) { if (workflowViewElement == null) { throw FxTrace.Exception.ArgumentNull("workflowViewElement"); } if (dragSource == null) { throw FxTrace.Exception.ArgumentNull("dragSource"); } workflowViewElement.SetValue(DragDropHelper.DragSourceProperty, dragSource); }
public static Visibility GetExpandCollapseButtonVisibility(WorkflowViewElement viewElement) { ActivityDesigner designer = viewElement as ActivityDesigner; bool hasDelegates = (designer != null) && designer.HasActivityDelegates; Visibility visibility = Visibility.Visible; if (viewElement == null || viewElement.IsRootDesigner || viewElement.DoesParentAlwaysExpandChild() || viewElement.DoesParentAlwaysCollapseChildren() || (viewElement.Content == null && !hasDelegates) || !viewElement.Collapsible || !(viewElement is ActivityDesigner)) { visibility = Visibility.Collapsed; } return visibility; }
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { bool isRootDesigner = true; if (values[0] is bool) { isRootDesigner = (bool)values[0]; } ModelItem modelItem = values[1] as ModelItem; WorkflowViewElement viewElement = values[2] as WorkflowViewElement; Fx.Assert(viewElement != null, "TemplatedParent should be of type WorkflowViewElement"); return(GetExpandCollapseButtonVisibility(viewElement)); }
public static Visibility GetExpandCollapseButtonVisibility(WorkflowViewElement viewElement) { ActivityDesigner designer = viewElement as ActivityDesigner; bool hasDelegates = (designer != null) && designer.HasActivityDelegates; Visibility visibility = Visibility.Visible; if (viewElement == null || viewElement.IsRootDesigner || viewElement.DoesParentAlwaysExpandChild() || viewElement.DoesParentAlwaysCollapseChildren() || (viewElement.Content == null && !hasDelegates) || !viewElement.Collapsible || !(viewElement is ActivityDesigner)) { visibility = Visibility.Collapsed; } return(visibility); }
private List <WorkflowViewElement> ObjectList2WorkflowViewElementList(IEnumerable <object> droppedObjects) { List <WorkflowViewElement> movedViewElements = new List <WorkflowViewElement>(); foreach (object droppedObject in droppedObjects) { if (droppedObject is ModelItem && ((ModelItem)droppedObject).View != null) { WorkflowViewElement view = (WorkflowViewElement)((ModelItem)droppedObject).View; WorkflowItemPresenter container = DragDropHelper.GetCompositeView(view) as WorkflowItemPresenter; if (container != this) { movedViewElements.Add(view); } } } return(movedViewElements); }
//This is more efficient than walking up the VisualTree looking for WorkflowViewElements. //Assuming that Cut-Copy will always be against selected elements. //This implies that only elements under the BreadCrumbRoot can be cut/copied. static List <WorkflowViewElement> GetSelectableParentViewElements(WorkflowViewElement childElement) { List <WorkflowViewElement> parentViewElements = new List <WorkflowViewElement>(); if (childElement != null) { UIElement breadcrumbRoot = childElement.Context.Services.GetService <DesignerView>().RootDesigner; ICompositeView container = (ICompositeView)DragDropHelper.GetCompositeView(childElement); while (!childElement.Equals(breadcrumbRoot) && container != null) { childElement = CutCopyPasteHelper.GetParentViewElement(container); Fx.Assert(childElement != null, "container should be present in a WorkflowViewElement"); parentViewElements.Add(childElement); container = (ICompositeView)DragDropHelper.GetCompositeView(childElement); } } return(parentViewElements); }
public static DragDropEffects DoDragMove(WorkflowViewElement draggedViewElement, Point referencePoint) { if (draggedViewElement == null) { throw FxTrace.Exception.ArgumentNull("draggedViewElement"); } if (referencePoint == null) { throw FxTrace.Exception.ArgumentNull("referencePoint"); } ModelItem draggedActivityModelItem = draggedViewElement.ModelItem; DataObject dataObject = new DataObject(ModelItemDataFormat, draggedActivityModelItem); dataObject.SetData(CompositeViewFormat, GetCompositeView(draggedViewElement)); dataObject.SetData(DragAnchorPointFormat, referencePoint); List <ModelItem> draggedModelItems = new List <ModelItem>(); draggedModelItems.Add(draggedActivityModelItem); dataObject.SetData(ModelItemsDataFormat, draggedModelItems); DesignerView view = draggedViewElement.Context.Services.GetService <DesignerView>(); ViewElementDragShadow dragShadow = new ViewElementDragShadow(view.scrollableContent, draggedViewElement, referencePoint, view.ZoomFactor); draggedViewElement.IsHitTestVisible = false; view.BeginDragShadowTracking(dragShadow); //whenever drag drop fails - ensure getting rid of drag shadow try { DragDrop.DoDragDrop(GetCompositeView(draggedViewElement), dataObject, DragDropEffects.Move | DragDropEffects.Copy | DragDropEffects.Scroll | DragDropEffects.Link); } catch { //let the caller handle exception throw; } finally { view.EndDragShadowTracking(dragShadow); draggedViewElement.IsHitTestVisible = true; } return(GetDragDropCompletedEffects(dataObject)); }
public ViewElementDragShadow(UIElement owner, WorkflowViewElement viewElement, Point offset, double scaleFactor) : base(owner) { Rect bounds = VisualTreeHelper.GetDescendantBounds(viewElement); this.width = bounds.Width; this.height = bounds.Height; this.content = new Rectangle() { Width = this.width, Height = this.height, Fill = new VisualBrush(viewElement) { Opacity = 0.6 } }; this.InitializeCommon(offset, scaleFactor); }
static void AddChildContainer(WorkflowViewElement viewElement, ICompositeView sourceContainer) { if (viewElement == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("viewElement")); } if (sourceContainer == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("sourceContainer")); } HashSet<ICompositeView> containers = (HashSet<ICompositeView>)viewElement.GetValue(CutCopyPasteHelper.ChildContainersProperty); if (containers == null) { containers = new HashSet<ICompositeView>(); viewElement.SetValue(CutCopyPasteHelper.ChildContainersProperty, containers); } containers.Add(sourceContainer); }
static void AddChildContainer(WorkflowViewElement viewElement, ICompositeView sourceContainer) { if (viewElement == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("viewElement")); } if (sourceContainer == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("sourceContainer")); } HashSet <ICompositeView> containers = (HashSet <ICompositeView>)viewElement.GetValue(CutCopyPasteHelper.ChildContainersProperty); if (containers == null) { containers = new HashSet <ICompositeView>(); viewElement.SetValue(CutCopyPasteHelper.ChildContainersProperty, containers); } containers.Add(sourceContainer); }
private bool IsInParentChain(ModelItem droppedModelItem) { bool isInParentChain = false; // start with immediate workflowviewElement outside this. WorkflowViewElement parentViewElement = GetParentWorkflowViewElement(); if (parentViewElement != null) { ModelItem parentModelItem = parentViewElement.ModelItem; while (parentModelItem != null) { if (parentModelItem == droppedModelItem) { isInParentChain = true; break; } parentModelItem = parentModelItem.Parent; } } return(isInParentChain); }
internal static void DoPaste(EditingContext context, Point pastePoint, WorkflowViewElement pastePointReference) { if (context == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("context")); } ModelItem modelItem = context.Items.GetValue <Selection>().PrimarySelection; if (modelItem == null) { return; } //Get data from clipboard. List <object> metaData = null; List <object> clipboardObjects = GetFromClipboard(out metaData, context); if (clipboardObjects != null) { using (EditingScope es = (EditingScope)modelItem.BeginEdit(SR.PasteUndoDescription)) { if (clipboardObjects.Count == 3 && clipboardObjects[1] is Func <ModelItem, object, object> ) { var factoryMethod = (Func <ModelItem, object, object>)clipboardObjects[1]; object result = factoryMethod(modelItem, clipboardObjects[2]); clipboardObjects = new List <object>(); clipboardObjects.Add(result); } ICompositeView container = GetContainerForPaste(modelItem, pastePoint); if (container != null) { container.OnItemsPasted(clipboardObjects, metaData, pastePoint, pastePointReference); } es.Complete(); } } }
private WorkflowViewElement GetParentWorkflowViewElement() { // Walk the logic tree first. FrameworkElement parent = (FrameworkElement)this.Parent; while (parent != null && !(parent is WorkflowViewElement)) { parent = parent.Parent as FrameworkElement; } WorkflowViewElement result = parent as WorkflowViewElement; // If not found, walk the visual tree. if (null == result) { parent = VisualTreeHelper.GetParent(this) as FrameworkElement; while (parent != null && !(parent is WorkflowViewElement)) { parent = VisualTreeHelper.GetParent(parent) as FrameworkElement; } result = parent as WorkflowViewElement; } return(result); }
internal static void DoCut(List <ModelItem> modelItemsToCut, EditingContext context) { if (modelItemsToCut == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("modelItemsToCut")); } if (context == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("context")); } modelItemsToCut.RemoveAll((modelItem) => { return(modelItem == null); }); if (modelItemsToCut.Count > 0) { using (EditingScope es = (EditingScope)modelItemsToCut[0].BeginEdit(SR.CutOperationEditingScopeDescription)) { try { CutCopyOperation(modelItemsToCut, context, true); } catch (ExternalException e) { es.Revert(); ErrorReporting.ShowErrorMessage(e.Message); return; } DesignerView view = context.Services.GetService <DesignerView>(); //Setting the selection to Breadcrumb root. Fx.Assert(view != null, "DesignerView Cannot be null during cut"); WorkflowViewElement rootView = view.RootDesigner as WorkflowViewElement; if (rootView != null) { Selection.SelectOnly(context, rootView.ModelItem); } es.Complete(); } } }
static void OnReadOnlyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { WorkflowViewElement viewElement = obj as WorkflowViewElement; viewElement.OnReadOnlyChanged((bool)e.NewValue); }
static void OnContextChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { WorkflowViewElement viewElement = obj as WorkflowViewElement; viewElement.OnContextChanged(); }
public WorkflowViewElementAutomationPeer(WorkflowViewElement owner) : base(owner) { this.owner = owner; }
public void OnItemsPasted(List<object> itemsToPaste, List<object> metaData, Point pastePoint, WorkflowViewElement pastePointReference) { if (this.ModelItem.ItemType == typeof(State)) { WorkflowViewElement view = VisualTreeUtils.FindVisualAncestor<WorkflowViewElement>(this); if (view != null) { StateContainerEditor container = (StateContainerEditor)DragDropHelper.GetCompositeView(view); container.OnItemsPasted(itemsToPaste, metaData, pastePoint, pastePointReference); } return; } if (itemsToPaste.Count == 1 && itemsToPaste.First() is Transition) { if (metaData == null || metaData.Count != 1 || !(metaData.First() is string)) { ShowMessageBox(SR.PasteTransitionWithoutDestinationState); return; } ModelItem destinationState = FindState(metaData.First() as string); if (destinationState == null) { ShowMessageBox(SR.PasteTransitionWithoutDestinationState); return; } this.PopulateVirtualizingContainer(destinationState); ModelItem[] selectedItems = this.Context.Items.GetValue<Selection>().SelectedObjects.ToArray(); string errorMessage; if (!CanPasteTransition(destinationState, out errorMessage, selectedItems)) { ShowMessageBox(errorMessage); return; } Transition pastedTransition = itemsToPaste.First() as Transition; Fx.Assert(pastedTransition != null, "Copied Transition should not be null."); using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(System.Activities.Presentation.SR.PropertyChangeEditingScopeDescription)) { string displayName = pastedTransition.DisplayName; bool isFirst = true; foreach (ModelItem selectedItem in selectedItems) { if (!isFirst) { StringReader reader = new StringReader(XamlServices.Save(pastedTransition)); pastedTransition = (Transition)XamlServices.Load(reader); } ModelItem transitionModelItem = this.Context.Services.GetRequiredService<ModelTreeManager>().WrapAsModelItem(pastedTransition); ModelItem sourceState = selectedItem; sourceState.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(transitionModelItem); transitionModelItem.Properties[TransitionDesigner.ToPropertyName].SetValue(destinationState); if (isFirst) { this.ViewStateService.RemoveViewState(transitionModelItem, ConnectorLocationViewStateKey); this.ViewStateService.RemoveViewState(transitionModelItem, SrcConnectionPointIndexStateKey); this.ViewStateService.RemoveViewState(transitionModelItem, DestConnectionPointIndexStateKey); isFirst = false; } } es.Complete(); } } else { List<ModelItem> modelItemsPasted = new List<ModelItem>(); List<State> states = new List<State>(); foreach (object obj in itemsToPaste) { State state; if (obj is FinalState) { state = new State() { DisplayName = DefaultFinalStateDisplayName, IsFinal = true }; } else { state = (State)obj; if (state.DisplayName == null) { state.DisplayName = DefaultStateDisplayName; } } states.Add(state); } RemoveDanglingTransitions(states); using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit( System.Activities.Presentation.SR.CollectionAddEditingScopeDescription)) { // Fix 157591 by storing the height and width of the container "before" the new states are added to the // panel, and group the insertion inside one editing scope - such that Undo will also restore the // size of the StateMachineContainer to pre-insert size. StoreShapeSizeWithUndoRecursively(this.ModelItem); foreach (State state in states) { ModelItem stateModelItem = (this.ModelItem.ItemType == typeof(StateMachine)) ? this.ModelItem.Properties[StateMachineDesigner.StatesPropertyName].Collection.Add(state) : GetStateMachineModelItem(this.ModelItem).Properties[StateMachineDesigner.StatesPropertyName].Collection.Add(state); modelItemsPasted.Add(stateModelItem); } es.Complete(); } if (modelItemsPasted.Count > 0) { // translate location view states to be in the coordinate system of the pasting target Fx.Assert(this.ModelItem.ItemType == typeof(StateMachine), "Only StateMachine contain the StateContainerEditor."); this.UpdateLocationViewStatesByMetaData(modelItemsPasted, metaData, this); if (pastePoint.X > 0 && pastePoint.Y > 0) { if (pastePointReference != null) { pastePoint = pastePointReference.TranslatePoint(pastePoint, this.panel); pastePoint.X = pastePoint.X < 0 ? 0 : pastePoint.X; pastePoint.Y = pastePoint.Y < 0 ? 0 : pastePoint.Y; } this.UpdateLocationViewStatesByPoint(modelItemsPasted, pastePoint); } // If paste point is not available, paste the items to the top left corner. else { this.UpdateLocationViewStatesToAvoidOverlap(modelItemsPasted); } } this.Dispatcher.BeginInvoke(() => { if (modelItemsPasted.Count > 0 && modelItemsPasted[0] != null) { Keyboard.Focus(modelItemsPasted[0].View as IInputElement); } this.Context.Items.SetValue(new Selection(modelItemsPasted)); }, DispatcherPriority.ApplicationIdle ); } }
public void OnItemsPasted(List<object> itemsToPaste, List<object> metaData, Point pastePoint, WorkflowViewElement pastePointReference) { Fx.Assert(this.panel != null, "This code shouldn't be hit if panel is null"); HashSet<Activity> workflowElementsPasted = new HashSet<Activity>(); List<ModelItem> modelItemsToSelect = new List<ModelItem>(); bool shouldStoreCurrentSizeViewState = true; Fx.Assert(this.ModelItem is IModelTreeItem, "this.ModelItem must implement IModelTreeItem"); using (EditingScope editingScope = ((IModelTreeItem)this.ModelItem).ModelTreeManager.CreateEditingScope(System.Activities.Presentation.SR.CollectionAddEditingScopeDescription)) { if (metaData != null) { List<ModelItem> modelItemsPerMetaData = new List<ModelItem>(); foreach (object designerMetaData in metaData) { if (designerMetaData is List<FlowNode>) { //This is flowchart metadata. foreach (FlowNode element in designerMetaData as List<FlowNode>) { FlowStep step = element as FlowStep; if (step != null) { workflowElementsPasted.Add(step.Action); } if (shouldStoreCurrentSizeViewState) { // Pasting may change the size of flowchart; need this to undo the size change. this.StoreCurrentSizeViewStateWithUndo(); shouldStoreCurrentSizeViewState = false; } ModelItem item = this.ModelItem.Properties["Nodes"].Collection.Add(element); // if the pasted item is a flowswitch but the default target is not in the pasted selection, // reset the DefaultCaseDisplayName to "Default". if (GenericFlowSwitchHelper.IsGenericFlowSwitch(item.ItemType) && item.Properties["Default"].Value == null) { item.Properties[FlowSwitchLabelFeature.DefaultCaseDisplayNamePropertyName].SetValue(FlowSwitchLabelFeature.DefaultCaseDisplayNameDefaultValue); } modelItemsPerMetaData.Add(item); if (item != null) { if (item.ItemType.Equals(typeof(FlowStep))) { modelItemsToSelect.Add(item.Properties["Action"].Value); } else { modelItemsToSelect.Add(item); } } } if (pastePoint.X > 0 && pastePoint.Y > 0) { Point panelPoint = this.TranslatePoint(pastePoint, this.panel); if (pastePointReference != null && !pastePointReference.Equals(this)) { if (pastePointReference.ModelItem != null && this.modelElement.ContainsKey(pastePointReference.ModelItem)) { panelPoint = pastePointReference.TranslatePoint(pastePoint, this.panel); } } panelPoint.X = panelPoint.X < 0 ? 0 : panelPoint.X; panelPoint.Y = panelPoint.Y < 0 ? 0 : panelPoint.Y; UpdateViewStateOnPastePoint(modelItemsPerMetaData, panelPoint); } else { UpdateViewStateToAvoidOverlapOnPaste(modelItemsPerMetaData); } modelItemsPerMetaData.Clear(); } } } foreach (object itemToPaste in itemsToPaste) { Activity workflowElementToPaste = itemToPaste as Activity; if (workflowElementToPaste != null && !workflowElementsPasted.Contains(workflowElementToPaste)) { FlowStep flowStep = new FlowStep { Action = workflowElementToPaste, Next = null }; if (shouldStoreCurrentSizeViewState) { // Pasting may change the size of flowchart; need this to undo the size change. this.StoreCurrentSizeViewStateWithUndo(); shouldStoreCurrentSizeViewState = false; } // When paste a non-flowstep object to flowchart, the existing hintsize of the object // should be removed, and let flowchart panel to compute the right size. VirtualizedContainerService.SetHintSize(workflowElementToPaste, null); ModelItem flowStepItem = this.ModelItem.Properties["Nodes"].Collection.Add(flowStep); if (flowStepItem != null) { modelItemsToSelect.Add(flowStepItem.Properties["Action"].Value); } } } editingScope.Complete(); } this.Dispatcher.BeginInvoke(() => { if (modelItemsToSelect.Count > 0 && modelItemsToSelect[0] != null) { Keyboard.Focus(modelItemsToSelect[0].View as IInputElement); } this.Context.Items.SetValue(new Selection(modelItemsToSelect)); }, DispatcherPriority.ApplicationIdle ); }
//This is more efficient than walking up the VisualTree looking for WorkflowViewElements. //Assuming that Cut-Copy will always be against selected elements. //This implies that only elements under the BreadCrumbRoot can be cut/copied. static List<WorkflowViewElement> GetSelectableParentViewElements(WorkflowViewElement childElement) { List<WorkflowViewElement> parentViewElements = new List<WorkflowViewElement>(); if (childElement != null) { UIElement breadcrumbRoot = childElement.Context.Services.GetService<DesignerView>().RootDesigner; ICompositeView container = (ICompositeView)DragDropHelper.GetCompositeView(childElement); while (!childElement.Equals(breadcrumbRoot) && container != null) { childElement = CutCopyPasteHelper.GetParentViewElement(container); Fx.Assert(childElement != null, "container should be present in a WorkflowViewElement"); parentViewElements.Add(childElement); container = (ICompositeView)DragDropHelper.GetCompositeView(childElement); } } return parentViewElements; }
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); } }
void OnItemsDropped(DragEventArgs e, int index) { ModelItemHelper.TryCreateImmediateEditingScopeAndExecute(this.Items.GetEditingContext(), System.Activities.Presentation.SR.CollectionAddEditingScopeDescription, (es) => { DragDropHelper.SetDragDropCompletedEffects(e, DragDropEffects.None); List <object> droppedObjects = new List <object>(DragDropHelper.GetDroppedObjects(this, e, Context)); List <WorkflowViewElement> movedViewElements = new List <WorkflowViewElement>(); List <object> externalMoveList = new List <object>(); List <ModelItem> internalMoveList = new List <ModelItem>(); // Step 1: Sort the list List <object> sortedDroppingList = DragDropHelper.SortSelectedObjects(droppedObjects); // Step 2: Categorize dropped objects by their source container. foreach (object droppedObject in sortedDroppingList) { ModelItem modelItem = droppedObject as ModelItem; WorkflowViewElement view = (modelItem == null) ? null : (modelItem.View as WorkflowViewElement); if (view == null) { externalMoveList.Add(droppedObject); continue; } UIElement container = DragDropHelper.GetCompositeView(view); if (container == this) { internalMoveList.Add(modelItem); continue; } movedViewElements.Add(view); externalMoveList.Add(droppedObject); } // Step 3: Internal movement if (this.ShouldMoveItems(internalMoveList, index)) { foreach (ModelItem modelItem in internalMoveList) { int oldIndex = this.Items.IndexOf(modelItem); this.Items.Remove(modelItem); //if element is placed ahead of old location, decrement the index not to include moved object if (oldIndex < index) { this.InsertItem(index - 1, modelItem); } else { this.InsertItem(index, modelItem); index++; } } } // Step 4: External move and drop from toolbox foreach (object droppedObject in externalMoveList) { if (!this.IsDropAllowed(droppedObject)) { continue; } this.InsertItem(index++, droppedObject); DragDropHelper.SetDragDropCompletedEffects(e, DragDropEffects.Move); } DragDropHelper.SetDragDropMovedViewElements(e, movedViewElements); e.Handled = true; if (es != null) { es.Complete(); } }); }
void ICompositeView.OnItemsPasted(List<object> itemsToPaste, List<object> metaData, Point pastePoint, WorkflowViewElement pastePointReference) { if (itemsToPaste.Count == 1) { // Single Paste UpdateItem(itemsToPaste[0]); } else { // Mutiple Paste. IList<object> sortedList = CutCopyPasteHelper.SortFromMetaData(itemsToPaste, metaData); Fx.Assert(this.Item == null, "multi-paste on item != null is not supported now"); this.DoAutoWrapDrop(InsertionPosition.None, sortedList); } }
void BeginDropAnimation(WorkflowViewElement target) { DropAnimation opacityAnimation = new DropAnimation(); target.BeginAnimation(FrameworkElement.OpacityProperty, opacityAnimation); }
void StoreShapeLocationViewState(WorkflowViewElement view, Point newLocation) { StoreShapeLocationViewState(view.ModelItem, newLocation); }
static void OnModelItemChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) { WorkflowViewElement viewElement = (WorkflowViewElement)dependencyObject; viewElement.OnModelItemChanged(e.NewValue); }
static HashSet<ICompositeView> GetChildContainers(WorkflowViewElement workflowViewElement) { HashSet<ICompositeView> childContainers = null; if (workflowViewElement != null && workflowViewElement.ShowExpanded) { childContainers = (HashSet<ICompositeView>)workflowViewElement.GetValue(CutCopyPasteHelper.ChildContainersProperty); } return childContainers; }
void PerformInternalMove(WorkflowViewElement movedElement, Point newPoint, Point shapeAnchorPoint) { using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(SR.ItemMove)) { RemoveAdorner(movedElement, typeof(ConnectionPointsAdorner)); Point newLocation = SnapVisualToGrid(movedElement, newPoint, shapeAnchorPoint); object viewState = this.ViewStateService.RetrieveViewState(movedElement.ModelItem, ShapeLocationViewStateKey); if (viewState != null) { Point oldLocation = (Point)viewState; // To make sure the connectors are still connected to the connection points this.OffsetConnectorViewState(movedElement.ModelItem, oldLocation, newLocation); } this.StoreShapeLocationViewState(movedElement, newLocation); // To make sure the connector changes are undoable this.StoreAttachedConnectorViewStates(movedElement); es.Complete(); } }
public void OnItemsPasted(List<object> itemsToPaste, List<object> metaData, Point pastePoint, WorkflowViewElement pastePointReference) { // first see if a spacer is selected. int index = this.selectedSpacerIndex; // else see if we can paste after a selected child if (index < 0) { Selection currentSelection = this.Context.Items.GetValue<Selection>(); index = this.Items.IndexOf(currentSelection.PrimarySelection); //paste after the selected child if (index >= 0) { index++; } } if (index < 0) { index = addAtEndMarker; } IList<object> mergedItemsToPaste = CutCopyPasteHelper.SortFromMetaData(itemsToPaste, metaData); List<ModelItem> modelItemsToSelect = new List<ModelItem>(); foreach (object itemToPaste in mergedItemsToPaste) { if (IsDropAllowed(itemToPaste)) { if (index == addAtEndMarker) { modelItemsToSelect.Add(this.Items.Add(itemToPaste)); } else { modelItemsToSelect.Add(this.Items.Insert(index, itemToPaste)); } if (index >= 0) { index++; } } } this.Dispatcher.BeginInvoke( new Action(() => { this.Context.Items.SetValue(new Selection(modelItemsToSelect)); }), Windows.Threading.DispatcherPriority.ApplicationIdle, null); }
public void OnItemsPasted(List <object> itemsToPaste, List <object> metaData, Point pastePoint, WorkflowViewElement pastePointReference) { // first see if a spacer is selected. int index = this.selectedSpacerIndex; // else see if we can paste after a selected child if (index < 0) { Selection currentSelection = this.Context.Items.GetValue <Selection>(); index = this.Items.IndexOf(currentSelection.PrimarySelection); //paste after the selected child if (index >= 0) { index++; } } if (index < 0) { index = addAtEndMarker; } IList <object> mergedItemsToPaste = CutCopyPasteHelper.SortFromMetaData(itemsToPaste, metaData); List <ModelItem> modelItemsToSelect = new List <ModelItem>(); foreach (object itemToPaste in mergedItemsToPaste) { if (IsDropAllowed(itemToPaste)) { if (index == addAtEndMarker) { modelItemsToSelect.Add(this.Items.Add(itemToPaste)); } else { modelItemsToSelect.Add(this.Items.Insert(index, itemToPaste)); } if (index >= 0) { index++; } } } this.Dispatcher.BeginInvoke( new Action(() => { this.Context.Items.SetValue(new Selection(modelItemsToSelect)); }), Windows.Threading.DispatcherPriority.ApplicationIdle, null); }
public void OnItemsPasted(List<object> itemsToPaste, List<object> metaData, Point pastePoint, WorkflowViewElement pastePointReference) { List<ModelItem> modelItemsPasted = new List<ModelItem>(); List<State> states = new List<State>(); foreach (object obj in itemsToPaste) { State state; if (obj is FinalState) { state = new State() { DisplayName = SR.DefaultFinalStateDisplayName, IsFinal = true }; } else { state = (State)obj; if (state.DisplayName == null) { state.DisplayName = SR.DefaultStateDisplayName; } } states.Add(state); } RemoveDanglingTransitions(states); foreach (State state in states) { ModelItem stateModelItem = this.ModelItem.Properties[ChildStatesPropertyName].Collection.Add(state); modelItemsPasted.Add(stateModelItem); } if (modelItemsPasted.Count > 0) { // translate location view states to be in the coordinate system of the pasting target this.UpdateLocationViewStatesByMetaData(modelItemsPasted, metaData); if (pastePoint.X > 0 && pastePoint.Y > 0) { if (pastePointReference != null) { pastePoint = pastePointReference.TranslatePoint(pastePoint, this.panel); pastePoint.X = pastePoint.X < 0 ? 0 : pastePoint.X; pastePoint.Y = pastePoint.Y < 0 ? 0 : pastePoint.Y; } this.UpdateLocationViewStatesByPoint(modelItemsPasted, pastePoint); } // If paste point is not available, paste the items to the top left corner. else { this.UpdateLocationViewStatesToTopLeft(modelItemsPasted); } } this.Context.Items.SetValue(new Selection(modelItemsPasted)); }
void RemoveStateVisual(WorkflowViewElement removedStateDesigner) { HashSet<Connector> connectorsToDelete = new HashSet<Connector>(); ModelService modelService = this.Context.Services.GetService<ModelService>(); List<UIElement> removedStateDesigners = new List<UIElement>(); removedStateDesigners.Add(removedStateDesigner); removedStateDesigners.AddRange(GetAllChildStateDesigners(removedStateDesigner)); StateContainerEditor outmostEditor = this.GetOutmostStateContainerEditor(); foreach (UIElement designer in removedStateDesigners) { if (outmostEditor.activeSrcConnectionPoint != null) { List<ConnectionPoint> connectionPoints = GetConnectionPoints(designer); if (connectionPoints.Contains(outmostEditor.activeSrcConnectionPoint)) { outmostEditor.activeSrcConnectionPoint = null; RemoveAdorner(outmostEditor.panel, typeof(ConnectorCreationAdorner)); } } if (outmostEditor.lastConnectionPointMouseUpElement == designer) { outmostEditor.lastConnectionPointMouseUpElement = null; } connectorsToDelete.UnionWith(GetAttachedConnectors(designer)); } // Remove any connector visuals attached to this shape. This is required for the scenarios as follows: // Copy and paste two connected States into StateMachine and undo the paste. // The Transition is not removed as a model change. Hence the connector visual will remain dangling on the designer. foreach (Connector connector in connectorsToDelete) { this.RemoveConnectorOnOutmostEditor(connector); } this.modelItemToUIElement.Remove(removedStateDesigner.ModelItem); removedStateDesigner.MouseEnter -= new MouseEventHandler(OnChildElementMouseEnter); removedStateDesigner.MouseLeave -= new MouseEventHandler(OnChildElementMouseLeave); ((FrameworkElement)removedStateDesigner).SizeChanged -= new SizeChangedEventHandler(OnChildElementSizeChanged); this.panel.Children.Remove(removedStateDesigner); // deselect removed item if (this.Context != null) { HashSet<ModelItem> selectedItems = new HashSet<ModelItem>(this.Context.Items.GetValue<Selection>().SelectedObjects); if (selectedItems.Contains(removedStateDesigner.ModelItem)) { Selection.Toggle(this.Context, removedStateDesigner.ModelItem); } } object locationOfShape = this.ViewStateService.RetrieveViewState(removedStateDesigner.ModelItem, StateContainerEditor.ShapeLocationViewStateKey); if (locationOfShape != null) { this.shapeLocations.Remove((Point)locationOfShape); } }
// Move the object to correct position after drop private void PostDropUpdateViewState(WorkflowViewElement view, ModelItem flownodeMI, AutoConnectDirections autoConnectDirection, Connector connectorToSplit, Point newPoint, Point anchorPoint, bool keepRelativePosition, ShapeOffsetter shapeOffsetter) { Fx.Assert((view != null && flownodeMI != null), "movedItem != null && flownodeMI != null"); Point shapeLocationPtr; if (autoConnectDirection != AutoConnectDirections.None) { shapeLocationPtr = this.CalculateDropLocationForAutoConnect(autoConnectDirection, view.DesiredSize); } else { shapeLocationPtr = SnapVisualToGrid(view, newPoint, anchorPoint, keepRelativePosition); if (!keepRelativePosition) { // To avoid overlaps shapeLocationPtr = shapeOffsetter.OffsetShapeLocation(shapeLocationPtr); } } if (connectorToSplit != null) { shapeLocationPtr = this.CalculateDropLocationForAutoSplit(newPoint, shapeLocationPtr, connectorToSplit, view.DesiredSize); } // if (keepRelativePosition) { this.OffsetDroppedItemToNewPosition(flownodeMI, shapeLocationPtr); } else { this.StoreShapeViewState(flownodeMI, shapeLocationPtr); } }
internal static void DoPaste(EditingContext context, Point pastePoint, WorkflowViewElement pastePointReference) { if (context == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("context")); } ModelItem modelItem = context.Items.GetValue<Selection>().PrimarySelection; if (modelItem == null) { return; } //Get data from clipboard. List<object> metaData = null; List<object> clipboardObjects = GetFromClipboard(out metaData, context); if (clipboardObjects != null) { using (EditingScope es = (EditingScope)modelItem.BeginEdit(SR.PasteUndoDescription)) { if (clipboardObjects.Count == 3 && clipboardObjects[1] is Func<ModelItem, object, object>) { var factoryMethod = (Func<ModelItem, object, object>)clipboardObjects[1]; object result = factoryMethod(modelItem, clipboardObjects[2]); clipboardObjects = new List<object>(); clipboardObjects.Add(result); } ICompositeView container = GetContainerForPaste(modelItem, pastePoint); if (container != null) { container.OnItemsPasted(clipboardObjects, metaData, pastePoint, pastePointReference); } es.Complete(); } } }