static List <ConnectionPoint> GetAllConnectionPoints(UIElement shape) { List <ConnectionPoint> allConnectionPoints = new List <ConnectionPoint>(6); allConnectionPoints.AddRange(FlowchartDesigner.GetConnectionPoints(shape)); allConnectionPoints.Add(FlowchartDesigner.GetTrueConnectionPoint(shape)); allConnectionPoints.Add(FlowchartDesigner.GetFalseConnectionPoint(shape)); return(allConnectionPoints); }
ConnectionPoint ConnectionPointHitTest(UIElement element, Point hitPoint) { List <ConnectionPoint> connectionPoints = new List <ConnectionPoint>(); List <ConnectionPoint> defaultConnectionPoints = FlowchartDesigner.GetConnectionPoints(element); connectionPoints.InsertRange(0, defaultConnectionPoints); connectionPoints.Add(FlowchartDesigner.GetTrueConnectionPoint(element)); connectionPoints.Add(FlowchartDesigner.GetFalseConnectionPoint(element)); return(FreeFormPanel.ConnectionPointHitTest(hitPoint, connectionPoints, this.panel)); }
Connector CreatePropertyLink(ModelItem srcModelItem, ModelItem propertyValue, string propertyName) { Connector newConnector = null; if (typeof(FlowStep).IsAssignableFrom(srcModelItem.ItemType)) { ModelItem src = GetCorrespondingElementOnCanvas(srcModelItem); ModelItem dest = GetCorrespondingElementOnCanvas(propertyValue); newConnector = CreateLink(modelElement[src], modelElement[dest], srcModelItem); } else if (typeof(FlowDecision).IsAssignableFrom(srcModelItem.ItemType)) { ModelItem dest = GetCorrespondingElementOnCanvas(propertyValue); ConnectionPoint srcConnPoint; if (propertyName.Equals("True")) { srcConnPoint = FlowchartDesigner.GetTrueConnectionPoint(modelElement[srcModelItem]); } else { srcConnPoint = FlowchartDesigner.GetFalseConnectionPoint(modelElement[srcModelItem]); } newConnector = CreateLink(srcConnPoint, modelElement[dest], srcModelItem); } else if (GenericFlowSwitchHelper.IsGenericFlowSwitch(srcModelItem.ItemType)) { ModelItem dest = GetCorrespondingElementOnCanvas(propertyValue); IFlowSwitchLink link; if (propertyName.Equals("Default")) { link = GenericFlowSwitchHelper.CreateFlowSwitchLink(srcModelItem.ItemType, srcModelItem, null, true); } else { Fx.Assert(propertyName.Length >= GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier.Length, "Case property names should be prepended by the string GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier"); link = GenericFlowSwitchHelper.CreateFlowSwitchLink(srcModelItem.ItemType, srcModelItem, propertyName.Substring(GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier.Length), false); } IModelTreeItem modelTreeItem = (IModelTreeItem)this.ModelItem; ModelItem linkModelItem = new FakeModelItemImpl(modelTreeItem.ModelTreeManager, link.GetType(), link, null); link.ModelItem = linkModelItem; newConnector = CreateLink(modelElement[srcModelItem], modelElement[dest], linkModelItem); } else // FlowStart { ModelItem dest = GetCorrespondingElementOnCanvas(propertyValue); newConnector = CreateLink(this.StartSymbol, modelElement[dest], this.ModelItem); } return(newConnector); }
protected override void OnRender(DrawingContext drawingContext) { const int textCulture = 9; ConnectionPoint trueConnectionPoint = null; ConnectionPoint falseConnectionPoint = null; if (this.connectionPoints.Contains(FlowchartDesigner.GetTrueConnectionPoint(this.AdornedElement))) { trueConnectionPoint = FlowchartDesigner.GetTrueConnectionPoint(this.AdornedElement); } if (this.connectionPoints.Contains(FlowchartDesigner.GetFalseConnectionPoint(this.AdornedElement))) { falseConnectionPoint = FlowchartDesigner.GetFalseConnectionPoint(this.AdornedElement); } Point actualPoint; Point origin = FreeFormPanel.GetLocation(AdornedElement); Thickness margin = ((FrameworkElement)AdornedElement).Margin; origin.X += margin.Left; origin.Y += margin.Top; foreach (ConnectionPoint connPoint in this.connectionPoints) { actualPoint = new Point(connPoint.Location.X - origin.X, connPoint.Location.Y - origin.Y); this.DrawConnectionPoint(connPoint, actualPoint, drawingContext); } if (trueConnectionPoint != null) { string trueLabelText = String.Empty; VirtualizedContainerService.VirtualizingContainer virtualizingContainer = (VirtualizedContainerService.VirtualizingContainer)trueConnectionPoint.ParentDesigner; if (virtualizingContainer != null && virtualizingContainer.ModelItem != null) { trueLabelText = (string)virtualizingContainer.ModelItem.Properties["TrueLabel"].ComputedValue; } actualPoint = new Point(trueConnectionPoint.Location.X - origin.X, trueConnectionPoint.Location.Y - origin.Y); FormattedText trueMarkerFormattedText = new FormattedText(trueLabelText, new System.Globalization.CultureInfo(textCulture), this.FlowDirection, FlowchartDesigner.FlowElementCaptionTypeface, FlowchartDesigner.FlowNodeCaptionFontSize, new SolidColorBrush(WorkflowDesignerColors.WorkflowViewElementCaptionColor)); actualPoint.Y += ConnectionPoint.DrawingLargeSide / 2; actualPoint.X -= trueMarkerFormattedText.WidthIncludingTrailingWhitespace; DrawtWithTransform( drawingContext, this.isTextRightToLeft, // Mirror the left side text to the right side by using this axis when RTL. actualPoint.X, () => { drawingContext.DrawText(trueMarkerFormattedText, actualPoint); }); } if (falseConnectionPoint != null) { string falseLabelText = String.Empty; VirtualizedContainerService.VirtualizingContainer virtualizingContainer = (VirtualizedContainerService.VirtualizingContainer)falseConnectionPoint.ParentDesigner; if (virtualizingContainer != null && virtualizingContainer.ModelItem != null) { falseLabelText = (string)virtualizingContainer.ModelItem.Properties["FalseLabel"].ComputedValue; } actualPoint = new Point(falseConnectionPoint.Location.X - origin.X, falseConnectionPoint.Location.Y - origin.Y); actualPoint.Y += ConnectionPoint.DrawingLargeSide / 2; FormattedText falseMarkerFormattedText = new FormattedText(falseLabelText, new System.Globalization.CultureInfo(textCulture), this.FlowDirection, FlowchartDesigner.FlowElementCaptionTypeface, FlowchartDesigner.FlowNodeCaptionFontSize, new SolidColorBrush(WorkflowDesignerColors.WorkflowViewElementCaptionColor)); DrawtWithTransform( drawingContext, this.isTextRightToLeft, // Mirror the left side text to the right side by using this axis when RTL. actualPoint.X, () => { drawingContext.DrawText(falseMarkerFormattedText, actualPoint); }); } base.OnRender(drawingContext); }
bool UpdateFlowChartObject(ConnectionPoint sourceConnPoint, ConnectionPoint destConnPoint, out string errorMessage, bool isLinkValidDueToLinkMove, IFlowSwitchLink caseKey) { //srcDesigner will be null for the case where source designer is StartSymbol. VirtualizedContainerService.VirtualizingContainer srcDesigner = sourceConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer; VirtualizedContainerService.VirtualizingContainer destDesigner = destConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer; ModelItem linkSource; ModelItem linkDest = destDesigner.ModelItem; ModelItem destFlowElementMI = GetFlowElementMI(linkDest); PointCollection connectorViewState = new PointCollection(ConnectorRouter.Route(this.panel, sourceConnPoint, destConnPoint)); errorMessage = string.Empty; if (sourceConnPoint.ParentDesigner is StartSymbol) { linkSource = this.ModelItem; if (linkSource.Properties["StartNode"].Value == null || isLinkValidDueToLinkMove) { this.StoreConnectorViewState(linkSource, connectorViewState, sourceConnPoint); linkSource.Properties["StartNode"].SetValue(destFlowElementMI); } else { errorMessage = SR.FCNextLinkDefined; } } else { linkSource = srcDesigner.ModelItem; ModelItem srcFlowElementMI = GetFlowElementMI(linkSource); if (typeof(FlowStep).IsAssignableFrom(srcFlowElementMI.ItemType)) { if (srcFlowElementMI.Properties["Next"].Value == null || isLinkValidDueToLinkMove) { this.StoreConnectorViewState(srcFlowElementMI, connectorViewState, sourceConnPoint); srcFlowElementMI.Properties["Next"].SetValue(destFlowElementMI); } else { errorMessage = SR.FCNextLinkDefined; } } else if (typeof(FlowDecision).IsAssignableFrom(srcFlowElementMI.ItemType)) { if (sourceConnPoint.Equals(FlowchartDesigner.GetTrueConnectionPoint(this.modelElement[linkSource]))) { if (linkSource.Properties["True"].Value == null || isLinkValidDueToLinkMove) { this.StoreConnectorViewState(srcFlowElementMI, connectorViewState, sourceConnPoint); linkSource.Properties["True"].SetValue(destFlowElementMI); } else { errorMessage = SR.FCTrueBranchExists; } } else if (sourceConnPoint.Equals(FlowchartDesigner.GetFalseConnectionPoint(this.modelElement[linkSource]))) { if (linkSource.Properties["False"].Value == null || isLinkValidDueToLinkMove) { this.StoreConnectorViewState(srcFlowElementMI, connectorViewState, sourceConnPoint); linkSource.Properties["False"].SetValue(destFlowElementMI); } else { errorMessage = SR.FCFalseBranchExists; } } else { errorMessage = SR.FCFlowConditionLinkError; } } else //FlowSwitch { if (!CreateFlowSwitchLink(sourceConnPoint, srcFlowElementMI, destFlowElementMI, caseKey, connectorViewState, ref errorMessage)) { return(false); } } } return(errorMessage.Equals(string.Empty)); }
internal Connector GetLinkOnCanvas(ModelItem srcFlowElementModelItem, ModelItem destflowElementModelItem, string propertyName) { Connector linkOnCanvas = null; ModelItem shapeModelItem = null; List <Connector> outGoingConnectors = null; if (!srcFlowElementModelItem.Equals(this.ModelItem)) { shapeModelItem = this.GetCorrespondingElementOnCanvas(srcFlowElementModelItem); outGoingConnectors = GetOutGoingConnectors(this.modelElement[shapeModelItem]); } else // Must be startNode { outGoingConnectors = GetOutGoingConnectors(this.StartSymbol); } foreach (Connector connector in outGoingConnectors) { ModelItem connectorDestModelItem = ((VirtualizedContainerService.VirtualizingContainer)FreeFormPanel.GetDestinationConnectionPoint(connector).ParentDesigner).ModelItem; ModelItem connectorDestFlowElementMI = this.GetFlowElementMI(connectorDestModelItem); //Following condition checks if the destination for current connector is equal to the destination passed in. if (destflowElementModelItem != null && destflowElementModelItem.Equals(connectorDestFlowElementMI)) { if (GenericFlowSwitchHelper.IsGenericFlowSwitch(srcFlowElementModelItem.ItemType)) { ModelItem linkModelItem = FlowchartDesigner.GetLinkModelItem(connector); if (linkModelItem.Properties["IsDefaultCase"].Value.GetCurrentValue().Equals(true) && propertyName.Equals("Default")) { linkOnCanvas = connector; break; } else { ModelItem connectorCaseMI = linkModelItem.Properties["Case"].Value; if (linkModelItem.Properties["IsDefaultCase"].Value.GetCurrentValue().Equals(false)) { string caseName = connectorCaseMI == null ? null : GenericFlowSwitchHelper.GetString(connectorCaseMI.GetCurrentValue(), connectorCaseMI.ItemType); if (connectorCaseMI != null && caseName.Equals(propertyName.Substring(GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier.Length))) { linkOnCanvas = connector; break; } else if (connectorCaseMI == null) { if (GenericFlowSwitchHelper.FlowSwitchNullCaseKeyIdentifier.Equals(propertyName.Substring(GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier.Length))) { linkOnCanvas = connector; break; } } } } } else if (typeof(FlowDecision).IsAssignableFrom(srcFlowElementModelItem.ItemType)) { ConnectionPoint trueConnPoint = FlowchartDesigner.GetTrueConnectionPoint(this.modelElement[shapeModelItem]); ConnectionPoint falseConnPoint = FlowchartDesigner.GetFalseConnectionPoint(this.modelElement[shapeModelItem]); ConnectionPoint connectorSrcConnPoint = FreeFormPanel.GetSourceConnectionPoint(connector); if ((propertyName.Equals("True") && connectorSrcConnPoint.Equals(trueConnPoint)) || (propertyName.Equals("False") && connectorSrcConnPoint.Equals(falseConnPoint))) { linkOnCanvas = connector; break; } } else //FlowStep case. { linkOnCanvas = connector; break; } } } return(linkOnCanvas); }
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); } }