/// <summary> /// Return true if there is diagram object that represents efelement/efobject in the diagram. /// </summary> /// <param name="efObject"></param> /// <returns></returns> internal bool IsEFObjectRepresentedInDiagram(EFObject efObject) { var entityTypesInDiagram = EntityTypeShapes.Select(ets => ets.EntityType.Target).ToList(); var entityType = efObject.GetParentOfType(typeof(ConceptualEntityType)) as ConceptualEntityType; var association = efObject.GetParentOfType(typeof(Association)) as Association; var associationSet = efObject as AssociationSet; var entitySet = efObject as EntitySet; // if efobject is an associationset, check if the corresponding association is in the diagram. if (associationSet != null && associationSet.Association.Status == BindingStatus.Known) { association = associationSet.Association.Target; } // if efobject is an entity-set, Return true only if all the entity-types contained in the set are represented in the diagram. if (entitySet != null) { foreach (var et in entitySet.GetEntityTypesInTheSet()) { if (entityTypesInDiagram.Contains(et) == false) { return(false); } } return(true); } else if (entityType != null) { return(entityTypesInDiagram.Contains(entityType)); } else if (association != null) { var associationsInDiagram = AssociationConnectors.Select(a => a.Association.Target).ToList(); return(associationsInDiagram.Contains(association)); } return(false); }
// Given an EFObject, this will transform it into something that should be referenceable in the explorer tree. internal static EFElement GetNavigationTargetForEFObject(EFObject efObject) { // find the first parent of EFObject that is an EFElement. This is what we want to navigate to. var efElement = efObject as EFElement; if (efElement == null) { efElement = efObject.GetParentOfType(typeof(EFElement)) as EFElement; } Debug.Assert(efElement != null, "Unable to find parent EFElement of EFObject"); var propertyRef = efElement as PropertyRef; var propertyRefContainer = efElement as PropertyRefContainer; if (propertyRef != null || propertyRefContainer != null) { Property target = null; if (propertyRef != null) { if (propertyRef.Name.Target != null) { target = propertyRef.Name.Target; efElement = target; } } else if (propertyRefContainer != null) { // use first referenced Property foreach (var pr in propertyRefContainer.PropertyRefs) { if (pr.Name.Target != null) { target = pr.Name.Target; efElement = target; break; } } } if (target == null) { // Couldn't find a property to reference, so try for a parent EntityType or Association. EFElement rtrn = efElement.GetParentOfType(typeof(EntityType)) as EntityType; if (rtrn == null) { rtrn = efElement.GetParentOfType(typeof(Association)) as Association; } Debug.Assert( rtrn != null, "Couldn't find EntityType or Association when swizzling EFObject of type " + efElement.GetType()); efElement = rtrn; } } else if (efElement is AssociationEnd) { Debug.Assert( efElement.Parent is Association, "Found unexpected parent type of AssociationEnd: " + efElement.Parent.GetType()); efElement = efElement.Parent as EFElement; } else if (efElement is AssociationSetEnd) { Debug.Assert( efElement.Parent is AssociationSet, "Found unexpected parent type of AssociationSetEnd: " + efElement.Parent.GetType()); efElement = efElement.Parent as EFElement; } else if (efElement is ReferentialConstraint) { Debug.Assert( efElement.Parent is Association, "Found unexpected parent type of ReferentialConstraint: " + efElement.Parent.GetType()); efElement = efElement.Parent as EFElement; } // some elements are not displayed in the Explorer - if so search for parent that is while (null != efElement && !EntityDesignModelToExplorerModelXRef.IsDisplayedInExplorer(efElement)) { efElement = efElement.Parent as EFElement; } return(efElement); }
/// <summary> /// This class will set the focus on the "most-appropriate" DSL node for the given EFObject and DSL Diagram. It is assumed that the /// EFObject is either a C-Space node, or an M-space node. /// </summary> internal static bool NavigateToDSLNodeInDiagram(EntityDesignerDiagram diagram, EFObject efobject) { var foundDSLElementMatchInDiagram = false; var context = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(efobject.Artifact.Uri); // find the model parent (if this is a c-space object) var cModel = efobject.GetParentOfType(typeof(ConceptualEntityModel)) as ConceptualEntityModel; // by default, we assume that this our c-space object var cspaceEFObject = efobject; EFObject mspaceEFObject = null; if (cModel == null) { var mModel = efobject.GetParentOfType(typeof(MappingModel)) as MappingModel; Debug.Assert(mModel != null, "efobject is neither in c-space or s-space"); // if this is a mapping node, then we want to find the closest corresponding c-space node // to which this mapping node is mapped, and set the focus on that. cspaceEFObject = GetCSpaceEFObjectForMSpaceEFObject(efobject); mspaceEFObject = efobject; } // navigate to the shape in the DSL designer var diagramItemCollection = new DiagramItemCollection(); RetrieveDiagramItemCollectionForEFObject(diagram, cspaceEFObject, diagramItemCollection); if (diagram != null && diagramItemCollection.Count > 0) { diagram.Show(); if (diagram.ActiveDiagramView != null) { diagram.ActiveDiagramView.Focus(); diagram.ActiveDiagramView.Selection.Set(diagramItemCollection); diagram.EnsureSelectionVisible(); } else { // If no active view exists, do the following: // - Set the selection on the first associated views (if any). // - Set InitialSelectionDIagramItemSelectionProperty to prevent the first EntityTypeShape to be selected (default behavior) // This case can happen when the diagram is not initialized or is not fully rendered. diagram.InitialDiagramItemSelection = diagramItemCollection; if (diagram.ClientViews != null && diagram.ClientViews.Count > 0) { foreach (DiagramClientView clientView in diagram.ClientViews) { clientView.Selection.Set(diagramItemCollection); clientView.Selection.EnsureVisible(DiagramClientView.EnsureVisiblePreferences.ScrollIntoViewCenter); break; } } } foundDSLElementMatchInDiagram = true; } if (mspaceEFObject != null) // navigate to the item in the mapping screen (if we are doing MSL items) { var mappingDetailsInfo = context.Items.GetValue <MappingDetailsInfo>(); if (mappingDetailsInfo.MappingDetailsWindow != null) { mappingDetailsInfo.MappingDetailsWindow.NavigateTo(mspaceEFObject); } } return(foundDSLElementMatchInDiagram); }
private static void RetrieveDiagramItemCollectionForEFObject( EntityDesignerDiagram diagram, EFObject efobject, DiagramItemCollection diagramItemCollection) { if (efobject == null) { return; } var cModel = efobject.RuntimeModelRoot() as ConceptualEntityModel; if (cModel == null) { // this either isn't a c-space object, or it is the ConceptualEntityModel node, so just return null return; } // if this is a child element of the association, return the diagram item for the association if (!(efobject is Association)) { var association = efobject.GetParentOfType(typeof(Association)) as Association; if (association != null) { RetrieveDiagramItemCollectionForEFObject(diagram, association, diagramItemCollection); return; } } if (efobject is Association) { var shapeElement = GetDesignerShapeElementForEFObject(diagram, efobject); if (shapeElement != null) { diagramItemCollection.Add(new DiagramItem(shapeElement)); return; } } else if (efobject is NavigationProperty) { var np = efobject as NavigationProperty; var shapeElement = GetDesignerShapeElementForEFObject(diagram, np.Parent); var entityTypeShape = shapeElement as EntityTypeShape; if (entityTypeShape != null) { // get the view model navigation property var vmNavProp = diagram.ModelElement.ModelXRef.GetExisting(np) as ViewModel.NavigationProperty; // try to create the DiagramItem from this if (vmNavProp != null) { var index = entityTypeShape.NavigationCompartment.Items.IndexOf(vmNavProp); if (index >= 0) { diagramItemCollection.Add( new DiagramItem( entityTypeShape.NavigationCompartment, entityTypeShape.NavigationCompartment.ListField, new ListItemSubField(index))); return; } } } } else if (efobject is Property) { var prop = efobject as Property; if (prop.IsComplexTypeProperty) { // complex type properties are not supported in the designer return; } var shapeElement = GetDesignerShapeElementForEFObject(diagram, prop.Parent); var entityTypeShape = shapeElement as EntityTypeShape; if (entityTypeShape != null) { // get the view model property var vmProp = diagram.ModelElement.ModelXRef.GetExisting(prop) as ViewModel.Property; if (vmProp != null) { var index = entityTypeShape.PropertiesCompartment.Items.IndexOf(vmProp); if (index >= 0) { diagramItemCollection.Add( new DiagramItem( entityTypeShape.PropertiesCompartment, entityTypeShape.PropertiesCompartment.ListField, new ListItemSubField(index))); return; } } } } else if (efobject is EntityType) { var shapeElement = GetDesignerShapeElementForEFObject(diagram, efobject); if (shapeElement != null) { diagramItemCollection.Add(new DiagramItem(shapeElement)); return; } } else if (efobject is EntitySet) { var es = efobject as EntitySet; foreach (var entityType in es.GetEntityTypesInTheSet()) { if (entityType != null) { RetrieveDiagramItemCollectionForEFObject(diagram, entityType, diagramItemCollection); } } return; } else if (efobject is AssociationSet) { // return a diagram item for the association var associationSet = efobject as AssociationSet; var association = associationSet.Association.Target; if (association != null) { RetrieveDiagramItemCollectionForEFObject(diagram, association, diagramItemCollection); return; } } else if (efobject is AssociationSetEnd) { var associationSetEnd = efobject as AssociationSetEnd; var end = associationSetEnd.Role.Target; if (end != null) { RetrieveDiagramItemCollectionForEFObject(diagram, end, diagramItemCollection); return; } else { var es = associationSetEnd.EntitySet.Target; if (es != null) { RetrieveDiagramItemCollectionForEFObject(diagram, es, diagramItemCollection); return; } } } else if (efobject is PropertyRef) { var pref = efobject as PropertyRef; if (pref.Name.Target != null) { RetrieveDiagramItemCollectionForEFObject(diagram, pref.Name.Target, diagramItemCollection); return; } } else if (efobject is PropertyRefContainer) { var prefContainer = efobject as PropertyRefContainer; // just use the first entry in the list. foreach (var pref in prefContainer.PropertyRefs) { RetrieveDiagramItemCollectionForEFObject(diagram, pref, diagramItemCollection); return; } } else if (efobject is EFAttribute) { // this is an EFAttribute node, so get the DiagramItem for the parent RetrieveDiagramItemCollectionForEFObject(diagram, efobject.Parent, diagramItemCollection); return; } else if (efobject is ConceptualEntityModel) { // nothing in the DSL surface to map to, so return null return; } else if (efobject is ConceptualEntityContainer) { // nothing in the DSL surface to map to, so return null return; } else if (efobject is FunctionImport) { // nothing in the DSL surface to map to, so return null return; } else { Debug.Fail("unexpected type of efobject. type = " + efobject.GetType()); if (efobject.Parent != null) { RetrieveDiagramItemCollectionForEFObject(diagram, efobject.Parent, diagramItemCollection); } } }
/// <summary> /// Given a efobject in m-space (ie, it is defined in the mapping section of the edmx file), find the /// closest object in the c-space (ie, defined in the conceptual schema). We do this by looking /// for binding objects of the current node bound to something in c-space. If there is no such object, we /// recursively call this on efobject's parent. /// </summary> /// <param name="efobject"></param> /// <returns></returns> private static EFObject GetCSpaceEFObjectForMSpaceEFObject(EFObject mspaceEFObject) { EFObject cspaceEFObject = null; var o = mspaceEFObject; // see if this m-space object has a parent of an association set mapping. var asm = mspaceEFObject.GetParentOfType(typeof(AssociationSetMapping)) as AssociationSetMapping; if (asm != null) { var associationSet = asm.Name.Target; if (associationSet != null) { var association = associationSet.Association.Target; if (association != null) { Debug.Assert( association.RuntimeModelRoot() is ConceptualEntityModel, "Expected association to be in C-space, but it is not!"); return(association); } } } // see if this is a node that requires the function view in the mapping pane var mfm = mspaceEFObject.GetParentOfType(typeof(ModificationFunctionMapping)) as ModificationFunctionMapping; var context = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(mspaceEFObject.Artifact.Uri); var mappingDetailsInfo = context.Items.GetValue <MappingDetailsInfo>(); if (mfm != null) { mappingDetailsInfo.EntityMappingMode = EntityMappingModes.Functions; } else { mappingDetailsInfo.EntityMappingMode = EntityMappingModes.Tables; } // default case, walk up the model looking for node that has a binding bound to something in c-space. while (cspaceEFObject == null && o != null) { var binding = o as ItemBinding; var container = o as EFContainer; if (binding != null) { // see if this binding is bound to something in c-space cspaceEFObject = GetCSpaceObjectFromBinding(binding); } else if (container != null) { // see if any direct children are bindings bound to something in c-space foreach (var child in container.Children) { // check every binding to see if it is bound to seomthing in cspace var b = child as ItemBinding; if (b != null) { cspaceEFObject = GetCSpaceObjectFromBinding(b); if (cspaceEFObject != null) { // break out of the for loop break; } } } } if (cspaceEFObject == null) { o = o.Parent; } } return(cspaceEFObject); }
// Given an EFObject, this will transform it into something that should be referenceable in the explorer tree. internal static EFElement GetNavigationTargetForEFObject(EFObject efObject) { // find the first parent of EFObject that is an EFElement. This is what we want to navigate to. var efElement = efObject as EFElement; if (efElement == null) { efElement = efObject.GetParentOfType(typeof(EFElement)) as EFElement; } Debug.Assert(efElement != null, "Unable to find parent EFElement of EFObject"); var propertyRef = efElement as PropertyRef; var propertyRefContainer = efElement as PropertyRefContainer; if (propertyRef != null || propertyRefContainer != null) { Property target = null; if (propertyRef != null) { if (propertyRef.Name.Target != null) { target = propertyRef.Name.Target; efElement = target; } } else if (propertyRefContainer != null) { // use first referenced Property foreach (var pr in propertyRefContainer.PropertyRefs) { if (pr.Name.Target != null) { target = pr.Name.Target; efElement = target; break; } } } if (target == null) { // Couldn't find a property to reference, so try for a parent EntityType or Association. EFElement rtrn = efElement.GetParentOfType(typeof(EntityType)) as EntityType; if (rtrn == null) { rtrn = efElement.GetParentOfType(typeof(Association)) as Association; } Debug.Assert( rtrn != null, "Couldn't find EntityType or Association when swizzling EFObject of type " + efElement.GetType()); efElement = rtrn; } } else if (efElement is AssociationEnd) { Debug.Assert( efElement.Parent is Association, "Found unexpected parent type of AssociationEnd: " + efElement.Parent.GetType()); efElement = efElement.Parent as EFElement; } else if (efElement is AssociationSetEnd) { Debug.Assert( efElement.Parent is AssociationSet, "Found unexpected parent type of AssociationSetEnd: " + efElement.Parent.GetType()); efElement = efElement.Parent as EFElement; } else if (efElement is ReferentialConstraint) { Debug.Assert( efElement.Parent is Association, "Found unexpected parent type of ReferentialConstraint: " + efElement.Parent.GetType()); efElement = efElement.Parent as EFElement; } // some elements are not displayed in the Explorer - if so search for parent that is while (null != efElement && !EntityDesignModelToExplorerModelXRef.IsDisplayedInExplorer(efElement)) { efElement = efElement.Parent as EFElement; } return efElement; }
/// <summary> /// This class will set the focus on the "most-appropriate" DSL node for the given EFObject and DSL Diagram. It is assumed that the /// EFObject is either a C-Space node, or an M-space node. /// </summary> internal static bool NavigateToDSLNodeInDiagram(EntityDesignerDiagram diagram, EFObject efobject) { var foundDSLElementMatchInDiagram = false; var context = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(efobject.Artifact.Uri); // find the model parent (if this is a c-space object) var cModel = efobject.GetParentOfType(typeof(ConceptualEntityModel)) as ConceptualEntityModel; // by default, we assume that this our c-space object var cspaceEFObject = efobject; EFObject mspaceEFObject = null; if (cModel == null) { var mModel = efobject.GetParentOfType(typeof(MappingModel)) as MappingModel; Debug.Assert(mModel != null, "efobject is neither in c-space or s-space"); // if this is a mapping node, then we want to find the closest corresponding c-space node // to which this mapping node is mapped, and set the focus on that. cspaceEFObject = GetCSpaceEFObjectForMSpaceEFObject(efobject); mspaceEFObject = efobject; } // navigate to the shape in the DSL designer var diagramItemCollection = new DiagramItemCollection(); RetrieveDiagramItemCollectionForEFObject(diagram, cspaceEFObject, diagramItemCollection); if (diagram != null && diagramItemCollection.Count > 0) { diagram.Show(); if (diagram.ActiveDiagramView != null) { diagram.ActiveDiagramView.Focus(); diagram.ActiveDiagramView.Selection.Set(diagramItemCollection); diagram.EnsureSelectionVisible(); } else { // If no active view exists, do the following: // - Set the selection on the first associated views (if any). // - Set InitialSelectionDIagramItemSelectionProperty to prevent the first EntityTypeShape to be selected (default behavior) // This case can happen when the diagram is not initialized or is not fully rendered. diagram.InitialDiagramItemSelection = diagramItemCollection; if (diagram.ClientViews != null && diagram.ClientViews.Count > 0) { foreach (DiagramClientView clientView in diagram.ClientViews) { clientView.Selection.Set(diagramItemCollection); clientView.Selection.EnsureVisible(DiagramClientView.EnsureVisiblePreferences.ScrollIntoViewCenter); break; } } } foundDSLElementMatchInDiagram = true; } if (mspaceEFObject != null) // navigate to the item in the mapping screen (if we are doing MSL items) { var mappingDetailsInfo = context.Items.GetValue<MappingDetailsInfo>(); if (mappingDetailsInfo.MappingDetailsWindow != null) { mappingDetailsInfo.MappingDetailsWindow.NavigateTo(mspaceEFObject); } } return foundDSLElementMatchInDiagram; }
/// <summary> /// Given a efobject in m-space (ie, it is defined in the mapping section of the edmx file), find the /// closest object in the c-space (ie, defined in the conceptual schema). We do this by looking /// for binding objects of the current node bound to something in c-space. If there is no such object, we /// recursively call this on efobject's parent. /// </summary> /// <param name="efobject"></param> /// <returns></returns> private static EFObject GetCSpaceEFObjectForMSpaceEFObject(EFObject mspaceEFObject) { EFObject cspaceEFObject = null; var o = mspaceEFObject; // see if this m-space object has a parent of an association set mapping. var asm = mspaceEFObject.GetParentOfType(typeof(AssociationSetMapping)) as AssociationSetMapping; if (asm != null) { var associationSet = asm.Name.Target; if (associationSet != null) { var association = associationSet.Association.Target; if (association != null) { Debug.Assert( association.RuntimeModelRoot() is ConceptualEntityModel, "Expected association to be in C-space, but it is not!"); return association; } } } // see if this is a node that requires the function view in the mapping pane var mfm = mspaceEFObject.GetParentOfType(typeof(ModificationFunctionMapping)) as ModificationFunctionMapping; var context = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(mspaceEFObject.Artifact.Uri); var mappingDetailsInfo = context.Items.GetValue<MappingDetailsInfo>(); if (mfm != null) { mappingDetailsInfo.EntityMappingMode = EntityMappingModes.Functions; } else { mappingDetailsInfo.EntityMappingMode = EntityMappingModes.Tables; } // default case, walk up the model looking for node that has a binding bound to something in c-space. while (cspaceEFObject == null && o != null) { var binding = o as ItemBinding; var container = o as EFContainer; if (binding != null) { // see if this binding is bound to something in c-space cspaceEFObject = GetCSpaceObjectFromBinding(binding); } else if (container != null) { // see if any direct children are bindings bound to something in c-space foreach (var child in container.Children) { // check every binding to see if it is bound to seomthing in cspace var b = child as ItemBinding; if (b != null) { cspaceEFObject = GetCSpaceObjectFromBinding(b); if (cspaceEFObject != null) { // break out of the for loop break; } } } } if (cspaceEFObject == null) { o = o.Parent; } } return cspaceEFObject; }