public static bool IsParentOf(this ModelItem item, ModelItem child) { if (null == item) { throw FxTrace.Exception.ArgumentNull("item"); } if (null == child) { throw FxTrace.Exception.ArgumentNull("child"); } bool isParent = false; child.GetParentEnumerator(p => { isParent = ModelItem.Equals(p, item); return(!isParent); }).LastOrDefault(); return(isParent); }
void OnPopulateContainer(VirtualizedContainerService.VirtualizingContainer virtualContainer) { if (this.shouldAbort) { return; } //if this is virutal container, it might contain multiple other virtual containers - i need to find the one //which either is a container for item i want to focus, or one which is parent designer for the item i'm looking for //look for the container which contains or is a parent of container i look for var target = virtualContainer .ChildContainers .FirstOrDefault(p => ModelItem.Equals(this.itemToFocus, p.ModelItem) || p.ModelItem.IsParentOf(this.itemToFocus)); //if one is found - populate it and bring it into view if (null != target) { target.Populate(); target.BringIntoView(); } }
//Expand method is executed repeatadly until maximum expand level is reached. it iterates through the model item tree //(from child up to MaximumExpandLevel parents) and tries to find first visible designer and populate it with content //If one elemnt is visited twice (denoted by currentItem argument) it means that expansion failed - (i.e. element is collapsed), //so i try to set that element as root designer and restart algoritm with that designer beeing new root void Expand(ModelItem currentItem) { //can i continue? if (this.shouldAbort) { return; } //stop condition - prevents infinite loop (the method is delegated into dispatcher, so it would never cause stack overflow if (0 > this.currentLevel) { ModelItemFocusHelper.focusTicket = null; return; } //browse direct parents, and Populate the fist one which is visible for (int index = 0; null != this.itemsToExpand && index < this.itemsToExpand.Length; ++index) { //is given parent visible? (it would return container for given model item) var container = this.ContainerService.QueryContainerForItem(this.itemsToExpand[index]); if (null != container) { //check if container we are trying to expand is not the same as the one in previous iteration //if it isn't --> populate its content if (!ModelItem.Equals(currentItem, this.itemsToExpand[index])) { this.Populate(container); return; } //if it is --> it means it is collapsed and further expand doesn't make sense. else if (null != currentItem) { int j = 0; //get index of item which we've tried to expand recently for (; j < this.itemsToExpand.Length; ++j) { if (ModelItem.Equals(this.itemsToExpand[j], currentItem)) { break; } } //starting at that point, see if given item can be a breadcrumb root for (int skipLevel = 0; j >= 0; --j) { currentItem = this.itemsToExpand[j]; //if it can - make it a new breadcrumb root and restart if (this.viewService.ShouldAppearOnBreadCrumb(currentItem, true)) { //make that designer a new root (don't set selection) this.DesignerView.MakeRootDesigner(currentItem, false); //and try to set focus with less maximum expand level, assuming that current designer is now expanded ModelItemFocusHelper.Focus(this.itemToFocus, this.currentLevel - skipLevel, this.shouldGetKeyboardFocus); return; } ++skipLevel; } //nothing in parent list can be made a breadcrumb, try set item which is supposed to get focus as a root if (this.viewService.ShouldAppearOnBreadCrumb(this.itemToFocus, true)) { this.DesignerView.MakeRootDesigner(this.itemToFocus, false); ModelItemFocusHelper.Focus(this.itemToFocus, 1, this.shouldGetKeyboardFocus); return; } //the item we want to set focus to, also cannot be displayed as root; //at this point - simply set selection to the current item, check if visibility has changed due to selection change this.Context.Items.SetValue(new Selection(currentItem)); Dispatcher.CurrentDispatcher.BeginInvoke(this.onElementFocusingDelegate, DispatcherPriority.ContextIdle, currentItem); //the final check - if item is still not visible, force it to be Dispatcher.CurrentDispatcher.BeginInvoke(this.onForceElementFocusDelegate, DispatcherPriority.ContextIdle); return; } } } ModelItemFocusHelper.focusTicket = null; //if we end up here and itemsToExpand is not null - something is wrong... //it is possible that algorithm stops here and itemsToExpand is null - this would be scenario when user tries to set focus to model item which cannot be //visualized and doesn't have any visual parent - i.e. Service or ActivityBuilder (they have a child property Body which can be visualized, but themselves - are not) if (null != this.itemsToExpand) { var displayProperty = this.itemToFocus.Properties["DisplayName"]; var displayName = displayProperty == null ? "(unknown)" : displayProperty.ComputedValue.ToString(); Fx.Assert("Expand is in invalid state - we should never end up here. Item to focus: " + displayName + " (" + this.itemToFocus.ItemType.Name + ")"); } }
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; }