bool ValidateCaseKey(object obj, out string reason) { return(GenericFlowSwitchHelper.ValidateCaseKey(obj, this.ModelItem.Properties["Cases"], this.genericType, out reason)); }
bool CreateFlowSwitchLink(ConnectionPoint sourceConnPoint, ModelItem srcFlowElementMI, ModelItem destFlowElementMI, IFlowSwitchLink caseKey, PointCollection connectorViewState, ref string errorMessage) { IModelTreeItem modelTreeItem = this.ModelItem as IModelTreeItem; if ((caseKey != null && caseKey.IsDefaultCase) || (caseKey == null && srcFlowElementMI.Properties["Default"].Value == null)) { IFlowSwitchLink link = GenericFlowSwitchHelper.CreateFlowSwitchLink(srcFlowElementMI.ItemType, srcFlowElementMI, null, true); ModelItem linkModelItem = new FakeModelItemImpl(modelTreeItem.ModelTreeManager, link.GetType(), link, null); link.ModelItem = linkModelItem; if (connectorViewState != null) { this.StoreConnectorViewState(linkModelItem, connectorViewState, sourceConnPoint); } srcFlowElementMI.Properties["Default"].SetValue(destFlowElementMI); } else { ModelProperty casesProp = srcFlowElementMI.Properties["Cases"]; string uniqueCaseName = null; if (caseKey == null) { Type typeArgument = srcFlowElementMI.ItemType.GetGenericArguments()[0]; if (GenericFlowSwitchHelper.CanBeGeneratedUniquely(typeArgument)) { uniqueCaseName = GenericFlowSwitchHelper.GetCaseName(casesProp, typeArgument, out errorMessage); } else { FlowSwitchCaseEditorDialog editor = new FlowSwitchCaseEditorDialog(srcFlowElementMI, this.Context, this, SR.AddNewCase, typeArgument); editor.WindowSizeToContent = SizeToContent.WidthAndHeight; if (!editor.ShowOkCancel()) { return(false); } uniqueCaseName = editor.CaseName; } } else { uniqueCaseName = caseKey.CaseName; } if (string.IsNullOrEmpty(errorMessage)) { IFlowSwitchLink link = GenericFlowSwitchHelper.CreateFlowSwitchLink(srcFlowElementMI.ItemType, srcFlowElementMI, uniqueCaseName, false); ModelItem linkModelItem = new FakeModelItemImpl(modelTreeItem.ModelTreeManager, link.GetType(), link, null); link.ModelItem = linkModelItem; if (connectorViewState != null) { this.StoreConnectorViewState(linkModelItem, connectorViewState, sourceConnPoint); } GenericFlowSwitchHelper.AddCase(srcFlowElementMI.Properties["Cases"], link.CaseObject, destFlowElementMI.GetCurrentValue()); } } return(true); }
//This method updates the clone of currentFlowElement to reference cloned FlowElements. void UpdateCloneReferences(FlowNode currentFlowElement, Dictionary <FlowNode, FlowNode> clonedFlowElements) { if (typeof(FlowStep).IsAssignableFrom(currentFlowElement.GetType())) { FlowStep currentFlowStep = (FlowStep)currentFlowElement; FlowStep clonedFlowStep = (FlowStep)clonedFlowElements[currentFlowElement]; FlowNode nextFlowElement = currentFlowStep.Next; if (nextFlowElement != null && clonedFlowElements.ContainsKey(nextFlowElement)) { clonedFlowStep.Next = clonedFlowElements[nextFlowElement]; } else { clonedFlowStep.Next = null; } } else if (typeof(FlowDecision).IsAssignableFrom(currentFlowElement.GetType())) { FlowDecision currentFlowDecision = (FlowDecision)currentFlowElement; FlowDecision clonedFlowDecision = (FlowDecision)clonedFlowElements[currentFlowElement]; FlowNode trueElement = currentFlowDecision.True; FlowNode falseElement = currentFlowDecision.False; if (trueElement != null && clonedFlowElements.ContainsKey(trueElement)) { clonedFlowDecision.True = clonedFlowElements[trueElement]; } else { clonedFlowDecision.True = null; } if (falseElement != null && clonedFlowElements.ContainsKey(falseElement)) { clonedFlowDecision.False = clonedFlowElements[falseElement]; } else { clonedFlowDecision.False = null; } } else if (GenericFlowSwitchHelper.IsGenericFlowSwitch(currentFlowElement.GetType())) { GenericFlowSwitchHelper.Copy(currentFlowElement.GetType().GetGenericArguments()[0], currentFlowElement, clonedFlowElements); } else { Debug.Fail("Unknown FlowNode"); } }
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); }
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { bool isDefaultCase = (bool)values[1]; if (isDefaultCase) { // Fx.Assert(values.Length == 3, "The multi-binding must have been constructed by FlowSwitchLink."); // For default case, we should have got three bindings. Two binding is possible when the linkModelItem is replaced but the view is not completely re-constructed yet. return(values.Length == 3 ? values[2] : null); } else { return(GenericFlowSwitchHelper.GetString(values[0], (Type)parameter)); } }
void OnCasePropertyChanged(DependencyPropertyChangedEventArgs e) { bool isUndoRedoInProgress = this.IsUndoRedoInProgress(); if (!this.internalChange && !isUndoRedoInProgress) { T oldValue = (T)e.OldValue; T newValue = (T)e.NewValue; if (newValue is string && newValue != null) { newValue = (T)((object)((string)((object)newValue)).Trim()); } string oldViewStateKey = string.Empty; if (!this.ContainsKey(newValue)) { using (EditingScope es = (EditingScope)this.flowSwitchModelItem.BeginEdit(SR.FlowSwitchCaseRenameEditingScopeDesc)) { ModelItem flowElementMI = null; flowElementMI = GenericFlowSwitchHelper.GetCaseModelItem(this.flowSwitchModelItem.Properties["Cases"], oldValue); GenericFlowSwitchHelper.RemoveCase(this.flowSwitchModelItem.Properties["Cases"], oldValue); oldViewStateKey = GenericFlowSwitchHelper.GetString(oldValue, typeof(T)) + CaseViewStateKeyAppendString; //Add the new value GenericFlowSwitchHelper.AddCase(this.flowSwitchModelItem.Properties["Cases"], newValue, flowElementMI.GetCurrentValue()); //Update the viewstate for the flowswitch. this.UpdateViewState(oldViewStateKey, GenericFlowSwitchHelper.GetString(newValue, typeof(T)) + CaseViewStateKeyAppendString); //Making sure the value for Case is always trimmed. this.internalChange = true; this.ModelItem.Properties["Case"].SetValue(newValue); es.Complete(); } } else { this.internalChange = true; this.CaseObject = oldValue; throw FxTrace.Exception.AsError(new InvalidOperationException(SR.InvalidFlowSwitchCaseMessage)); } } this.internalChange = false; }
// 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]); } }
public static bool ValidateCaseKey(object obj, ModelProperty casesProp, Type genericType, out string reason) { reason = string.Empty; string key = GenericFlowSwitchHelper.GetString(obj, genericType); if (GenericFlowSwitchHelper.CheckEquality(obj, genericType)) { if (GenericFlowSwitchHelper.ContainsCaseKey(casesProp, obj)) { reason = string.Format(CultureInfo.CurrentCulture, SR.DuplicateCaseKey, key); return(false); } return(true); } else { reason = string.Format(CultureInfo.CurrentUICulture, SR.EqualityError, genericType.Name); return(false); } }
void RefreshFlowSwitchLinkModelItem(ModelItem flowSwitchModelItem, Connector connector, bool isDefault) { ModelItem oldLinkModelItem = FlowchartDesigner.GetLinkModelItem(connector); IModelTreeItem modelTreeItem = flowSwitchModelItem as IModelTreeItem; IFlowSwitchLink link = GenericFlowSwitchHelper.CreateFlowSwitchLink(flowSwitchModelItem.ItemType, flowSwitchModelItem, ((IFlowSwitchLink)oldLinkModelItem.GetCurrentValue()).CaseObject, isDefault); ModelItem linkModelItem = new FakeModelItemImpl(modelTreeItem.ModelTreeManager, link.GetType(), link, null); link.ModelItem = linkModelItem; FlowchartDesigner.SetLinkModelItem(connector, linkModelItem); connector.SetBinding(Connector.LabelTextProperty, link.CreateConnectorLabelTextBinding()); Selection currentSelection = this.Context.Items.GetValue <Selection>(); if (currentSelection.SelectedObjects.Contains(oldLinkModelItem)) { Selection.Toggle(this.Context, oldLinkModelItem); Selection.Select(this.Context, linkModelItem); } }
void OnIsDefaultPropertyChanged(DependencyPropertyChangedEventArgs e) { bool isUndoRedoInProgress = this.IsUndoRedoInProgress(); if (!this.internalDefaultCaseChange && !isUndoRedoInProgress) { bool value = (bool)e.NewValue; bool oldValue = (bool)e.OldValue; if (value) { if (object.Equals(this.flowSwitchModelItem.Properties["Default"].Value, null)) { using (EditingScope es = (EditingScope)this.flowSwitchModelItem.BeginEdit(SR.FlowSwitchCaseRenameEditingScopeDesc)) { ModelItem flowNodeMI = GenericFlowSwitchHelper.GetCaseModelItem(this.flowSwitchModelItem.Properties["Cases"], this.CaseObject); GenericFlowSwitchHelper.RemoveCase(this.flowSwitchModelItem.Properties["Cases"], this.CaseObject); this.flowSwitchModelItem.Properties["Default"].SetValue(flowNodeMI); this.UpdateViewState(this.CaseName + CaseViewStateKeyAppendString, DefaultConnectorViewStateKey); this.internalChange = true; es.Complete(); } } else { this.internalDefaultCaseChange = true; this.IsDefaultCase = oldValue; throw FxTrace.Exception.AsError(new InvalidOperationException(SR.DefaultCaseExists)); } } else { if (oldValue) { using (EditingScope es = (EditingScope)this.flowSwitchModelItem.BeginEdit(SR.FlowSwitchCaseRenameEditingScopeDesc)) { ModelItem defaultCase = this.flowSwitchModelItem.Properties["Default"].Value; object uniqueCase = null; string errorMessage = string.Empty; Type typeArgument = typeof(T); if (GenericFlowSwitchHelper.CanBeGeneratedUniquely(typeArgument)) { string caseName = GenericFlowSwitchHelper.GetCaseName(this.flowSwitchModelItem.Properties["Cases"], typeArgument, out errorMessage); if (!string.IsNullOrEmpty(errorMessage)) { this.internalDefaultCaseChange = true; this.IsDefaultCase = oldValue; throw FxTrace.Exception.AsError(new InvalidOperationException(errorMessage)); } uniqueCase = GenericFlowSwitchHelper.GetObject(caseName, typeArgument); } else { FlowSwitchCaseEditorDialog editor = new FlowSwitchCaseEditorDialog(this.flowSwitchModelItem, ((WorkflowViewElement)this.flowSwitchModelItem.View).Context, this.flowSwitchModelItem.View, SR.ChangeCaseValue, this.flowSwitchModelItem.ItemType.GetGenericArguments()[0]); editor.WindowSizeToContent = SizeToContent.WidthAndHeight; if (!editor.ShowOkCancel()) { this.internalDefaultCaseChange = true; this.IsDefaultCase = oldValue; return; } uniqueCase = editor.Case; if (GenericFlowSwitchHelper.ContainsCaseKey(this.flowSwitchModelItem.Properties["Cases"], uniqueCase)) { this.internalDefaultCaseChange = true; this.IsDefaultCase = oldValue; throw FxTrace.Exception.AsError(new InvalidOperationException(SR.InvalidFlowSwitchCaseMessage)); } } this.flowSwitchModelItem.Properties["Default"].SetValue(null); this.flowSwitchModelItem.Properties[FlowSwitchLabelFeature.DefaultCaseDisplayNamePropertyName].SetValue(FlowSwitchLabelFeature.DefaultCaseDisplayNameDefaultValue); this.internalChange = true; if (typeof(string) != typeof(T)) { this.ModelItem.Properties["Case"].SetValue(uniqueCase); GenericFlowSwitchHelper.AddCase(this.flowSwitchModelItem.Properties["Cases"], uniqueCase, defaultCase.GetCurrentValue()); } else { this.ModelItem.Properties["Case"].SetValue(uniqueCase); GenericFlowSwitchHelper.AddCase(this.flowSwitchModelItem.Properties["Cases"], uniqueCase, defaultCase.GetCurrentValue()); } this.UpdateViewState(DefaultConnectorViewStateKey, GenericFlowSwitchHelper.GetString(uniqueCase, typeof(T)) + CaseViewStateKeyAppendString); es.Complete(); this.internalChange = false; } this.internalDefaultCaseChange = false; } } } this.internalDefaultCaseChange = false; }
private IFlowSwitchLink DeleteLinkImpl(Connector link, bool isMoveOrAutoSplit = false, HashSet <ModelItem> referenceUpdatedModelItems = null) { IFlowSwitchLink caseKey = null; ModelItem linkModelItem = FlowchartDesigner.GetLinkModelItem(link); if (referenceUpdatedModelItems != null && referenceUpdatedModelItems.Contains(linkModelItem)) { return(caseKey); } ConnectionPoint srcConnectionPoint = FreeFormPanel.GetSourceConnectionPoint(link); ConnectionPoint destConnectionPoint = FreeFormPanel.GetDestinationConnectionPoint(link); if (typeof(FlowStep).IsAssignableFrom(linkModelItem.ItemType)) { linkModelItem.Properties["Next"].SetValue(null); } else if (typeof(FlowDecision).IsAssignableFrom(linkModelItem.ItemType)) { //Determine if it is True or False branch. if (srcConnectionPoint.Equals(FlowchartDesigner.GetTrueConnectionPoint(srcConnectionPoint.ParentDesigner))) { //True branch linkModelItem.Properties["True"].SetValue(null); } else { linkModelItem.Properties["False"].SetValue(null); } } else if (typeof(IFlowSwitchLink).IsAssignableFrom(linkModelItem.ItemType)) { IFlowSwitchLink flowSwitchLink = (IFlowSwitchLink)linkModelItem.GetCurrentValue(); caseKey = flowSwitchLink; //Transitioning from the fakeModelItem world to the real ModelItem world. FlowNode fs = flowSwitchLink.ParentFlowSwitch; ModelItem realFlowSwitchMI = (this.ModelItem as IModelTreeItem).ModelTreeManager.WrapAsModelItem(fs); if (referenceUpdatedModelItems != null && referenceUpdatedModelItems.Contains(realFlowSwitchMI)) { return(caseKey); } if (flowSwitchLink.IsDefaultCase) { realFlowSwitchMI.Properties["Default"].SetValue(null); if (!isMoveOrAutoSplit) { realFlowSwitchMI.Properties[FlowSwitchLabelFeature.DefaultCaseDisplayNamePropertyName].SetValue(FlowSwitchLabelFeature.DefaultCaseDisplayNameDefaultValue); } } else { GenericFlowSwitchHelper.RemoveCase(realFlowSwitchMI.Properties["Cases"], flowSwitchLink.CaseObject); } } else // StartNode { this.ModelItem.Properties["StartNode"].SetValue(null); } this.StoreConnectorViewState(linkModelItem, null, srcConnectionPoint, true); return(caseKey); }
public static ModelItem GetCaseModelItem(ModelProperty casesProp, object key) { ModelItemCollection itemsCollection = casesProp.Value.Properties["ItemsCollection"].Collection; return(GenericFlowSwitchHelper.GetCaseModelItem(itemsCollection, key)); }
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 ); }
// The logic is similar to UpdateCloneReferences. // the difference is in this function, we need to set reference by Property. void UpdateCloneReferenceByModelItem(FlowNode currentFlowElement, Dictionary <FlowNode, ModelItem> modelItems, Dictionary <FlowNode, FlowNode> clonedFlowElements) { if (typeof(FlowStep).IsAssignableFrom(currentFlowElement.GetType())) { FlowStep currentFlowStep = (FlowStep)currentFlowElement; FlowStep clonedFlowStep = (FlowStep)clonedFlowElements[currentFlowElement]; ModelItem modelItem = modelItems[clonedFlowStep]; FlowNode nextFlowElement = currentFlowStep.Next; if (nextFlowElement != null && clonedFlowElements.ContainsKey(nextFlowElement)) { modelItem.Properties["Next"].SetValue(clonedFlowElements[nextFlowElement]); } else { modelItem.Properties["Next"].SetValue(null); } } else if (typeof(FlowDecision).IsAssignableFrom(currentFlowElement.GetType())) { if (!modelItems.ContainsKey(currentFlowElement)) { Fx.Assert("Should not happen."); } FlowDecision currentFlowDecision = (FlowDecision)currentFlowElement; FlowDecision clonedFlowDecision = (FlowDecision)clonedFlowElements[currentFlowElement]; Fx.Assert(currentFlowDecision == clonedFlowDecision, "should not happen"); ModelItem modelItem = modelItems[currentFlowElement]; Fx.Assert(modelItem != null, "should not happen"); FlowNode trueElement = currentFlowDecision.True; FlowNode falseElement = currentFlowDecision.False; if (trueElement != null && clonedFlowElements.ContainsKey(trueElement)) { modelItem.Properties["True"].SetValue(clonedFlowElements[trueElement]); } else { modelItem.Properties["True"].SetValue(null); } if (falseElement != null && clonedFlowElements.ContainsKey(falseElement)) { modelItem.Properties["False"].SetValue(clonedFlowElements[falseElement]); } else { modelItem.Properties["False"].SetValue(null); } } else if (GenericFlowSwitchHelper.IsGenericFlowSwitch(currentFlowElement.GetType())) { GenericFlowSwitchHelper.ReferenceCopy(currentFlowElement.GetType().GetGenericArguments()[0], currentFlowElement, modelItems, clonedFlowElements); } else { Debug.Fail("Unknown FlowNode"); } }
public static object GetCase(ModelItemCollection itemsCollection, object key) { return(GenericFlowSwitchHelper.GetCaseModelItem(itemsCollection, key).GetCurrentValue()); }
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); }
public static string GenericGetCaseName <T>(ModelItemCollection collection, out string errorMessage) { int maxName = 100000; Type type = typeof(T); errorMessage = string.Empty; if (typeof(string).IsAssignableFrom(type)) { string caseName = "caseN"; for (int i = 1; i <= maxName; i++) { caseName = string.Format(CultureInfo.InvariantCulture, SR.CaseFormat, i); if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, caseName)) { break; } } return(caseName); } else if (GenericFlowSwitchHelper.IsIntegralType(type)) { if (type == typeof(sbyte)) { sbyte maxCount = (sbyte.MaxValue < maxName) ? sbyte.MaxValue : (sbyte)maxName; for (sbyte i = 0; i <= maxCount; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return(GenericFlowSwitchHelper.GetString(i, type)); } } } else if (type == typeof(byte)) { byte maxCount = (byte.MaxValue < maxName) ? byte.MaxValue : (byte)maxName; for (byte i = 0; i <= maxCount; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return(GenericFlowSwitchHelper.GetString(i, type)); } } } else if (type == typeof(char)) { char maxCount = unchecked ((char)maxName); for (char i = (char)48; i <= maxCount; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return(GenericFlowSwitchHelper.GetString(i, type)); } } } else if (type == typeof(short)) { short maxCount = (short)maxName; for (short i = 0; i <= maxCount; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return(GenericFlowSwitchHelper.GetString(i, type)); } } } else if (type == typeof(ushort)) { ushort maxCount = (ushort)maxName; for (ushort i = 0; i <= maxCount; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return(GenericFlowSwitchHelper.GetString(i, type)); } } } else if (type == typeof(int)) { for (int i = 0; i <= maxName; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return(GenericFlowSwitchHelper.GetString(i, type)); } } } else if (type == typeof(uint)) { for (uint i = 0; i <= (uint)maxName; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return(GenericFlowSwitchHelper.GetString(i, type)); } } } else if (type == typeof(long)) { for (long i = 0; i <= (long)maxName; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return(GenericFlowSwitchHelper.GetString(i, type)); } } } else if (type == typeof(ulong)) { for (ulong i = 0; i <= (ulong)maxName; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return(GenericFlowSwitchHelper.GetString(i, type)); } } } errorMessage = SR.InvalidFlowSwitchCaseMessage; return(string.Empty); } else if (type.IsEnum) { Array array = type.GetEnumValues(); foreach (object value in array) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, value)) { return(GenericFlowSwitchHelper.GetString(value, type)); } } errorMessage = SR.InvalidFlowSwitchCaseMessage; return(string.Empty); } else if (type == typeof(bool)) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, true)) { return(GenericFlowSwitchHelper.GetString(true, type)); } else if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, false)) { return(GenericFlowSwitchHelper.GetString(false, type)); } errorMessage = SR.InvalidFlowSwitchCaseMessage; return(string.Empty); } return(string.Empty); }
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); } }
//For flowchart reacting to ModelItem changes we are concerned of the following scenarios: //1. FlowElements being deleted from the Flowchart.Nodes collection or Flowswitch cases being deleted from ItemsCollection //2. FlowElements being added to the Flowchart.Nodes collection or Flowswitch cases being added from ItemsCollection //3. Properties being changed in FlowStep(Next), FlowDecision(True, false), FlowSwitch(Default) (Any of the flowelemnet should be present in the elements collection). //4. Flowswitch cases being added/remove via Cases.Dicitionary void ModelTreeManager_EditingScopeCompleted(object sender, EditingScopeEventArgs e) { Fx.Assert(this.panel != null, "This code should not be hit if panel is null"); foreach (Change change in e.EditingScope.Changes) { //Case 1, 2. if (change is CollectionChange) { CollectionChange collectionChange = change as CollectionChange; if (collectionChange.Collection.Equals(this.ModelItem.Properties["Nodes"].Collection)) { if (collectionChange.Operation == CollectionChange.OperationType.Delete) { this.DeleteShapeVisual(this.flowNodeToUIElement[collectionChange.Item]); } else { this.AddFlowElementsToDesigner(new List <ModelItem> { collectionChange.Item }); //An editing scope change references the ModelItem. //Hence in case of multiple changes to the same modelItem within the same EditingScope, we will see all the changes on the ModelItem for each change. //Eg. Suppose following two changes are in the same editing scope: 1. Add ModelItem item1 to Collection, 2. Change a property on this MI, item1.Prop1 //In this case, EditingScope.Changes.Count will be 2. //Since an EditingScope change keeps a reference to the ModelItem changed, when we process the first change, the second change would already be reflected on the ModelItem. //Hence, while processing CollectionChange for item1, item1.Prop1 will already reflect the new value. //Also there will be another change notifying the change in item1.Prop1. //AddFlowElementsToDesigner() method, walks through the properties of a newly added item and creates any links if required. //This is necessary for Paste scenario where we want to create links between Items added to the Nodes Collection. //Because of this behavior of AddFlowElementsToDesigner(), before reacting to a property change for adding a link, we will always verify that the link does not already exists. } } if (collectionChange.Collection.Parent != null && collectionChange.Collection.Parent.Parent != null && this.ModelItem.Properties["Nodes"].Collection.Contains(collectionChange.Collection.Parent.Parent) && collectionChange.Collection.Parent.Parent.ItemType.IsGenericType && collectionChange.Collection.Parent.Parent.ItemType.GetGenericTypeDefinition() == typeof(FlowSwitch <>)) { ModelItem item = collectionChange.Item; string caseName = GenericFlowSwitchHelper.GetString(item.Properties["Key"].ComputedValue, item.Properties["Key"].PropertyType); Connector connector = this.GetLinkOnCanvas(collectionChange.Collection.Parent.Parent, item.Properties["Value"].Value, GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier + caseName); if (collectionChange.Operation == CollectionChange.OperationType.Delete) { if (connector != null) { this.DeleteLinkVisual(connector); } } else if (collectionChange.Operation == CollectionChange.OperationType.Insert) { if (connector == null) { //Prepending GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier to differentiate between the FlowSwitch's Property Default and key Default. connector = this.CreatePropertyLink(collectionChange.Collection.Parent.Parent, item.Properties["Value"].Value, GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier + caseName); Fx.Assert(connector != null, "Link not created"); this.panel.Children.Add(connector); } else { RefreshFlowSwitchLinkModelItem(/* flowSwitchModelItem = */ collectionChange.Collection.Parent.Parent, connector, false); } } } } else if (change is DictionaryChange) { // case 4 DictionaryChange dictionaryChange = change as DictionaryChange; if (dictionaryChange.Dictionary.Parent != null && this.ModelItem.Properties["Nodes"].Collection.Contains(dictionaryChange.Dictionary.Parent) && dictionaryChange.Dictionary.Parent.ItemType.IsGenericType && dictionaryChange.Dictionary.Parent.ItemType.GetGenericTypeDefinition() == typeof(FlowSwitch <>)) { ModelItem flowSwitchModelItem = dictionaryChange.Dictionary.Parent; ModelItem caseTargetModelItem = dictionaryChange.Value; string caseName = GenericFlowSwitchHelper.GetString(dictionaryChange.Key == null ? null : dictionaryChange.Key.GetCurrentValue(), dictionaryChange.Key == null ? null : dictionaryChange.Key.ItemType); string caseNameInModelItem = GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier + caseName; Connector connector = this.GetLinkOnCanvas( flowSwitchModelItem, caseTargetModelItem, caseNameInModelItem); if (dictionaryChange.Operation == DictionaryChange.OperationType.Delete) { if (connector != null) { this.DeleteLinkVisual(connector); } } else if (dictionaryChange.Operation == DictionaryChange.OperationType.Insert) { if (connector == null) { connector = this.CreatePropertyLink( flowSwitchModelItem, caseTargetModelItem, caseNameInModelItem); this.panel.Children.Add(connector); } } } } //Case 3. else if (change is PropertyChange) { PropertyChange propertyChange = change as PropertyChange; if (this.ModelItem.Properties["Nodes"].Collection.Contains(propertyChange.Owner) || (propertyChange.PropertyName == "StartNode" && propertyChange.Owner == this.ModelItem)) { if (propertyChange.OldValue != null && IsFlowNode(propertyChange.OldValue)) { Connector link = GetLinkOnCanvas(propertyChange.Owner, propertyChange.OldValue, propertyChange.PropertyName); //Debug.Assert(link != null, "Link not found on designer"); if (link != null) { this.DeleteLinkVisual(link); } } if (propertyChange.NewValue != null && IsFlowNode(propertyChange.NewValue)) { Connector oldLink = GetLinkOnCanvas(propertyChange.Owner, propertyChange.NewValue, propertyChange.PropertyName); //If this connector has already been added don't add again. if (oldLink == null) { Connector link = CreatePropertyLink(propertyChange.Owner, propertyChange.NewValue, propertyChange.PropertyName); Fx.Assert(link != null, "Link not created"); this.panel.Children.Add(link); } else { if (GenericFlowSwitchHelper.IsGenericFlowSwitch(propertyChange.Owner.ItemType)) { this.RefreshFlowSwitchLinkModelItem(/* flowSwitchModelItem = */ propertyChange.Owner, oldLink, true); } } } //handling for the case where the FlowStep.Action changes: //Explicitly adding a check for FlowStep, because other FlowNodes have properties of type Activity, which we don't want to react to. //AddFlowElementsToDesigner() will add the links originating out of the shape that is changing. //We have to take care of refreshing the links coming into the shape that is changing. if (typeof(FlowStep).IsAssignableFrom(propertyChange.Owner.ItemType)) { List <Connector> oldIncomingConnectors = new List <Connector>(); if (propertyChange.OldValue != null && IsFlowStepAction(propertyChange.OldValue)) { UIElement oldShape = this.flowNodeToUIElement[propertyChange.Owner]; oldIncomingConnectors = this.GetInComingConnectors(oldShape); this.DeleteShapeVisual(oldShape); } if (propertyChange.NewValue != null && IsFlowStepAction(propertyChange.NewValue)) { this.AddFlowElementsToDesigner(new List <ModelItem> { propertyChange.Owner }); foreach (Connector oldConnector in oldIncomingConnectors) { Connector newConnector = CreateLink(FreeFormPanel.GetSourceConnectionPoint(oldConnector), this.flowNodeToUIElement[propertyChange.Owner], FlowchartDesigner.GetLinkModelItem(oldConnector)); this.panel.Children.Add(newConnector); } } } } } } }
void OnViewStateChanged(object sender, ViewStateChangedEventArgs e) { Fx.Assert(this.panel != null, "This code should not be hit if panel is null"); Fx.Assert(e.ParentModelItem != null, "ViewState should be associated with some modelItem"); Connector changedConnector = null; if (e.ParentModelItem == this.ModelItem) { if (string.Equals(e.Key, FlowchartSizeFeature.WidthPropertyName, StringComparison.Ordinal)) { this.FlowchartWidth = (double)TypeDescriptor.GetProperties(this.ModelItem)[FlowchartSizeFeature.WidthPropertyName].GetValue(this.ModelItem); } else if (string.Equals(e.Key, FlowchartSizeFeature.HeightPropertyName, StringComparison.Ordinal)) { this.FlowchartHeight = (double)TypeDescriptor.GetProperties(this.ModelItem)[FlowchartSizeFeature.HeightPropertyName].GetValue(this.ModelItem); } } if ((IsFlowNode(e.ParentModelItem) || this.ModelItem.Equals(e.ParentModelItem)) && !this.internalViewStateChange) { ModelItem itemOnCanvas = this.GetCorrespondingElementOnCanvas(e.ParentModelItem); if (this.modelElement.ContainsKey(itemOnCanvas)) { if (e.Key.Equals(shapeLocation)) { if (e.NewValue != null) { FreeFormPanel.SetLocation(this.modelElement[itemOnCanvas], (Point)e.NewValue); this.panel.InvalidateMeasure(); if (e.OldValue != null) { this.shapeLocations.Remove((Point)e.OldValue); } this.shapeLocations.Add((Point)e.NewValue); } } else { if (this.ModelItem.Equals(e.ParentModelItem) && e.Key.Equals(ConnectorViewStateKey)) { changedConnector = this.GetLinkOnCanvas(e.ParentModelItem, e.ParentModelItem.Properties["StartNode"].Value, "StartNode"); } else if (typeof(FlowStep).IsAssignableFrom(e.ParentModelItem.ItemType) && e.Key.Equals(ConnectorViewStateKey)) { changedConnector = this.GetLinkOnCanvas(e.ParentModelItem, e.ParentModelItem.Properties["Next"].Value, "Next"); } else if (typeof(FlowDecision).IsAssignableFrom(e.ParentModelItem.ItemType)) { if (e.Key.Equals(TrueConnectorViewStateKey)) { changedConnector = this.GetLinkOnCanvas(e.ParentModelItem, e.ParentModelItem.Properties["True"].Value, "True"); } else if (e.Key.Equals(FalseConnectorViewStateKey)) { changedConnector = this.GetLinkOnCanvas(e.ParentModelItem, e.ParentModelItem.Properties["False"].Value, "False"); } } else if (GenericFlowSwitchHelper.IsGenericFlowSwitch(e.ParentModelItem.ItemType)) { if (e.Key.Equals(FlowchartDesigner.FlowSwitchDefaultViewStateKey, StringComparison.CurrentCulture)) { changedConnector = this.GetLinkOnCanvas(e.ParentModelItem, e.ParentModelItem.Properties["Default"].Value, e.Key); } else if (e.Key.EndsWith(CaseViewStateKeyAppendString, StringComparison.CurrentCulture)) { string switchCaseName = e.Key.Substring(0, e.Key.Length - CaseViewStateKeyAppendString.Length); object switchCase = switchCaseName; Type genericType = e.ParentModelItem.ItemType.GetGenericArguments()[0]; switchCase = GenericFlowSwitchHelper.GetObject(switchCaseName, genericType); if (GenericFlowSwitchHelper.ContainsCaseKey(e.ParentModelItem.Properties["Cases"], switchCase)) { //Prepending with GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier to differentiate between the property Default and the key Default. changedConnector = this.GetLinkOnCanvas(e.ParentModelItem, GenericFlowSwitchHelper.GetCaseModelItem(e.ParentModelItem.Properties["Cases"], switchCase), GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier + switchCase); } } } } } } if (changedConnector != null) { if (e.NewValue != null) { Fx.Assert(e.NewValue is PointCollection, "e.NewValue is not PointCollection"); changedConnector.Points = e.NewValue as PointCollection; this.panel.RemoveConnectorEditor(); this.panel.InvalidateMeasure(); } } }
public static bool CanBeGeneratedUniquely(Type typeArgument) { return(typeArgument.IsEnum || typeof(string).IsAssignableFrom(typeArgument) || GenericFlowSwitchHelper.IsIntegralType(typeArgument) || typeof(bool) == typeArgument); }