// oldNewFlowNodeMap: <OldFlowNode, NewFlowNode> // sometimes, OldFlowNode == NewFlowNode, say, FlowNode is a FlowDecesion. // if FlowNode is FlowStep, OldFlowNode != NewFlowNode public static void GenericRemapFlowSwitch <T>(FlowNode currentFlowElement, ModelItem modelItem, Dictionary <FlowNode, FlowNode> oldNewFlowNodeMap) { FlowSwitch <T> currentFlowSwitch = (FlowSwitch <T>)currentFlowElement; //Update the default case. FlowNode defaultCase = currentFlowSwitch.Default; if (defaultCase != null && oldNewFlowNodeMap.ContainsKey(defaultCase)) { modelItem.Properties["Default"].SetValue(oldNewFlowNodeMap[defaultCase]); } else { modelItem.Properties["Default"].SetValue(null); } // collect all the cases that should be update Dictionary <object, object> keyValueMap = new Dictionary <object, object>(); foreach (T key in currentFlowSwitch.Cases.Keys) { if (oldNewFlowNodeMap.ContainsKey(currentFlowSwitch.Cases[key])) { keyValueMap.Add(key, oldNewFlowNodeMap[currentFlowSwitch.Cases[key]]); } } // Update the Cases dictionary. ModelProperty casesProperty = modelItem.Properties["Cases"]; // remove all key foreach (ModelItem key in GenericFlowSwitchHelper.GetCaseKeys(casesProperty)) { GenericFlowSwitchHelper.RemoveCase(casesProperty, key.GetCurrentValue()); } // add back keys foreach (T key in keyValueMap.Keys) { GenericFlowSwitchHelper.AddCase(casesProperty, key, keyValueMap[key]); } }
void AddFlowElementsToDesigner(IList <ModelItem> flowElementMICollection, bool addConnectorAfterLoaded = false) { Queue <ModelItem> flowElementsToProcess = new Queue <ModelItem>(); List <UIElement> viewsAdded = new List <UIElement>(); foreach (ModelItem model in flowElementMICollection) { ModelItem itemOnCanvas = GetCorrespondingElementOnCanvas(model); if (!this.modelElement.ContainsKey(itemOnCanvas)) { flowElementsToProcess.Enqueue(model); viewsAdded.Add(ProcessAndGetModelView(itemOnCanvas)); } else if (!this.panel.Children.Contains(this.modelElement[itemOnCanvas])) { flowElementsToProcess.Enqueue(model); viewsAdded.Add(this.modelElement[itemOnCanvas]); } } ModelItem startNodeModelItem = null; List <Tuple <UIElement, UIElement, ModelItem> > elem2elemConnections = new List <Tuple <UIElement, UIElement, ModelItem> >(); List <Tuple <ConnectionPoint, UIElement, ModelItem> > point2elemConnections = new List <Tuple <ConnectionPoint, UIElement, ModelItem> >(); while (flowElementsToProcess.Count > 0) { ModelItem currentMI = flowElementsToProcess.Dequeue(); //Create links for the current FlowNode. //First of all check if this is connected to the start node. if (this.ModelItem.Properties["StartNode"].Value != null && this.ModelItem.Properties["StartNode"].Value.Equals(currentMI)) { startNodeModelItem = currentMI; } if (typeof(FlowStep).IsAssignableFrom(currentMI.ItemType)) { ModelItem linkDest = currentMI.Properties["Next"].Value; if (linkDest != null) { ModelItem src = GetCorrespondingElementOnCanvas(currentMI); ModelItem dest = GetCorrespondingElementOnCanvas(linkDest); if (!modelElement.ContainsKey(dest)) { viewsAdded.Add(ProcessAndGetModelView(dest)); flowElementsToProcess.Enqueue(linkDest); } elem2elemConnections.Add(Tuple.Create(modelElement[src], modelElement[dest], currentMI)); } } else if (typeof(FlowDecision).IsAssignableFrom(currentMI.ItemType)) { ModelItem trueDest = currentMI.Properties["True"].Value; ModelItem falseDest = currentMI.Properties["False"].Value; if (trueDest != null) { ConnectionPoint srcConnectionPoint = FlowchartDesigner.GetTrueConnectionPoint(modelElement[currentMI]); ModelItem trueDestOnCanvas = GetCorrespondingElementOnCanvas(trueDest); if (!modelElement.ContainsKey(trueDestOnCanvas)) { viewsAdded.Add(ProcessAndGetModelView(trueDestOnCanvas)); flowElementsToProcess.Enqueue(trueDest); } point2elemConnections.Add(Tuple.Create(srcConnectionPoint, modelElement[trueDestOnCanvas], currentMI)); } if (falseDest != null) { ConnectionPoint srcConnectionPoint = FlowchartDesigner.GetFalseConnectionPoint(modelElement[currentMI]); ModelItem falseDestOnCanvas = GetCorrespondingElementOnCanvas(falseDest); if (!modelElement.ContainsKey(falseDestOnCanvas)) { viewsAdded.Add(ProcessAndGetModelView(falseDestOnCanvas)); flowElementsToProcess.Enqueue(falseDest); } point2elemConnections.Add(Tuple.Create(srcConnectionPoint, modelElement[falseDestOnCanvas], currentMI)); } } else if (GenericFlowSwitchHelper.IsGenericFlowSwitch(currentMI.ItemType)) { IModelTreeItem modelTreeItem = this.ModelItem as IModelTreeItem; ModelItem defaultCase = currentMI.Properties["Default"].Value; if (defaultCase != null) { ModelItem defaultCaseOnCanvas = GetCorrespondingElementOnCanvas(defaultCase); if (!modelElement.ContainsKey(defaultCaseOnCanvas)) { viewsAdded.Add(ProcessAndGetModelView(defaultCaseOnCanvas)); flowElementsToProcess.Enqueue(defaultCase); } IFlowSwitchLink link = GenericFlowSwitchHelper.CreateFlowSwitchLink(currentMI.ItemType, currentMI, null, true); ModelItem linkModelItem = new FakeModelItemImpl(modelTreeItem.ModelTreeManager, link.GetType(), link, null); link.ModelItem = linkModelItem; elem2elemConnections.Add(Tuple.Create(modelElement[currentMI], modelElement[defaultCaseOnCanvas], linkModelItem)); } Type genericType = currentMI.ItemType.GetGenericArguments()[0]; foreach (ModelItem key in GenericFlowSwitchHelper.GetCaseKeys(currentMI.Properties["Cases"])) { ModelItem destFlowElementMI = GenericFlowSwitchHelper.GetCaseModelItem(currentMI.Properties["Cases"], (key == null) ? null : key.GetCurrentValue()); IFlowSwitchLink link = GenericFlowSwitchHelper.CreateFlowSwitchLink(currentMI.ItemType, currentMI, (key == null) ? null : key.GetCurrentValue(), false); ModelItem linkModelItem = new FakeModelItemImpl(modelTreeItem.ModelTreeManager, link.GetType(), link, null); link.ModelItem = linkModelItem; ModelItem destModelItem = GetCorrespondingElementOnCanvas(destFlowElementMI); if (!modelElement.ContainsKey(destModelItem)) { viewsAdded.Add(ProcessAndGetModelView(destModelItem)); flowElementsToProcess.Enqueue(destFlowElementMI); } elem2elemConnections.Add(Tuple.Create(modelElement[currentMI], modelElement[destModelItem], linkModelItem)); } } else { Fx.Assert(false, "Unknown type of FlowNode"); } } if (!this.startNodeAdded) { panel.Children.Add(this.StartSymbol); this.startNodeAdded = true; } foreach (UIElement view in viewsAdded) { panel.Children.Add(view); } // connection between flownode should be create only after all flownodes have been loaded on the canvas if (addConnectorAfterLoaded) { this.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() => { if (this.isLoaded) { AddConnectorsToPanel(startNodeModelItem, elem2elemConnections, point2elemConnections); } })); } else { AddConnectorsToPanel(startNodeModelItem, elem2elemConnections, point2elemConnections); } }