public SequenceDiagramViewModel( IServiceControl serviceControl, ISettingsProvider settingsProvider, MessageSelectionContext selectionContext, DiagramLegendViewModel diagramLegend, CopyConversationIDCommand copyConversationIDCommand, CopyMessageURICommand copyMessageURICommand, RetryMessageCommand retryMessageCommand, SearchByMessageIDCommand searchByMessageIDCommand, ChangeSelectedMessageCommand changeSelectedMessageCommand, ShowExceptionCommand showExceptionCommand, ReportMessageCommand reportMessageCommand) { this.serviceControl = serviceControl; this.settingsProvider = settingsProvider; Selection = selectionContext; CopyConversationIDCommand = copyConversationIDCommand; CopyMessageURICommand = copyMessageURICommand; RetryMessageCommand = retryMessageCommand; SearchByMessageIDCommand = searchByMessageIDCommand; ChangeSelectedMessageCommand = changeSelectedMessageCommand; ShowExceptionCommand = showExceptionCommand; ReportMessageCommand = reportMessageCommand; OpenLink = Command.Create(arg => new NetworkOperations().Browse(SequenceDiagramDocumentationUrl)); DiagramLegend = diagramLegend; DiagramItems = new DiagramItemCollection(); HeaderItems = new DiagramItemCollection(); settings = settingsProvider.GetSettings <SequenceDiagramSettings>(); ShowLegend = settings.ShowLegend; }
public override void OnMouseDown(DiagramMouseEventArgs e) { base.OnMouseDown(e); DiagramItem diagramItem = e.HitDiagramItem; Column referenceColumn = ResolveColumn(diagramItem); if (referenceColumn != null) { // See if we're dragging other columns DiagramItemCollection selection = e.DiagramClientView.Selection.TopLevelItems; Table table = referenceColumn.Table; int count = selection.Count; Column[] selectedColumns = new Column[count]; for (int i = 0; i < count; ++i) { Column column = ResolveColumn(selection[i]); if (null == column || (column != referenceColumn && column.Table != table)) { return; } selectedColumns[i] = column; } myDragSourceColumns = selectedColumns; myDragSourceShape = (ColumnElementListCompartment)diagramItem.Shape; } else { myDragSourceColumns = null; myDragSourceShape = null; } }
internal static void SelectDiagramItems( this EntityDesignerView.EntityDesignerDiagram entityDesignerDiagram, ShapeElement[] shapeElements) { var diagramItemCollection = new DiagramItemCollection(); foreach (var shapeElement in shapeElements) { diagramItemCollection.Add(new DiagramItem(shapeElement)); } if (entityDesignerDiagram.ActiveDiagramView != null) { entityDesignerDiagram.ActiveDiagramView.Focus(); entityDesignerDiagram.ActiveDiagramView.Selection.Set(diagramItemCollection); entityDesignerDiagram.EnsureSelectionVisible(); } else { // if no active diagram view is available, set the selection in any client view. if (entityDesignerDiagram.ClientViews != null && entityDesignerDiagram.ClientViews.Count > 0) { foreach (DiagramClientView clientView in entityDesignerDiagram.ClientViews) { clientView.Selection.Set(diagramItemCollection); clientView.Selection.EnsureVisible(DiagramClientView.EnsureVisiblePreferences.ScrollIntoViewCenter); break; } } else { throw new InvalidOperationException("There is no active client views in the diagram."); } } }
/// <summary> /// Replaces the current emphasis list with a new emphasis list. /// </summary> /// <param name="diagramItems">The collection of DiagramItems that is to replace the current emphasis list.</param> /// <remarks> /// If the DiagramItemCollection is null, then the emphasis list is cleared. /// </remarks> internal void Set(DiagramItemCollection diagramItems) { Invalidate(); // Invalidate to ensure that the old shapes will be repainted. List.Clear(); if (diagramItems != null) { Add(diagramItems); Invalidate(); } }
/// <summary> /// Adds the specified DiagramItems to the current emphasis list. /// </summary> /// <remarks> /// If a DiagramItem in the collection is already in the emphasis list, the DiagramItem is ignored. /// </remarks> /// <param name="diagramItems">The collection of DiagramItems to add.</param> private void Add(DiagramItemCollection diagramItems) { // only add shapes that are not currently in the emphasis list. foreach (var diagramItem in diagramItems) { if (!Contains(diagramItem)) { base.Add(diagramItem); } } }
public DiagramNode(Diagram diagram) : base(diagram) { _label = new DiagramLabel(diagram, this); _label.NeedRecalc = true; _edges = new DiagramItemCollection<DiagramEdge>(diagram); IsUnderCursor = false; if (!diagram.Nodes.Contains(this)) diagram.Nodes.Add(this); }
public override void Execute(IMenuCommand command) { var viewModel = new AddAutomationExtensionViewModel(this.AutomationSettings.Select(l => l.Metadata)); var view = this.DialogFactory(viewModel); if (view.ShowDialog().GetValueOrDefault()) { var diagramItems = new DiagramItemCollection(); var clientView = this.View.CurrentDesigner.DiagramClientView; foreach (var target in this.CurrentSelection) { var element = target as IPatternElementSchema; var automationSchema = element.CreateAutomationSettingsSchema(aes => { var aesMel = (ModelElement)aes; var extension = aesMel.AddExtension(viewModel.CurrentExportedAutomation.ExportingType); string displayName = extension.GetDomainClass().DisplayName; aes.Name = aesMel.GetUniqueName(SanitizeName(displayName)); aes.AutomationType = displayName; aes.Classification = ((IAutomationSettings)extension).Classification; }); var shape = PresentationViewsSubject.GetPresentation((PatternElementSchema)element).OfType <CompartmentShape>().FirstOrDefault(); if (shape != null) { var diagramItem = shape.FindDiagramItem <AutomationSettingsSchema>(a => a.Id == automationSchema.Id); if (diagramItem != null) { diagramItems.Add(diagramItem); } } } clientView.Selection.Set(diagramItems); } }
/// <summary> /// Highlight both the name shape and the corresponding role box. /// </summary> public override void OnMouseEnter(DiagramPointEventArgs e) { DiagramClientView clientView; FactTypeShape parentShape; Role role; if (null != (clientView = e.DiagramClientView) && null != (parentShape = ParentShape as FactTypeShape) && null != (role = this.ModelElement as Role)) { DiagramItemCollection items = new DiagramItemCollection(); items.Add(new DiagramItem(this)); items.Add(parentShape.GetDiagramItem(role)); clientView.HighlightedShapes.Set(items); } else { base.OnMouseEnter(e); } }
/// <summary> /// Executes the specified command. /// </summary> /// <param name="command">The command.</param> public override void Execute(IMenuCommand command) { var propertyContainerSchemas = this.CurrentSelection.Cast <PatternElementSchema>(); // Warn user if changing tailored extension point contract var extensionPoints = propertyContainerSchemas.OfType <ExtensionPointSchema>(); if (extensionPoints.Any(ext => ext.IsInheritedFromBase) && extensionPoints.Any(ext => ext.Properties.All(p => p.IsInheritedFromBase))) { var resume = this.MessageService.PromptWarning(Properties.ShellResources.AddVariablePropertyCommand_BreakContractWarning); if (!resume) { return; } } var diagramItems = new DiagramItemCollection(); var clientView = this.View.CurrentDesigner.DiagramClientView; foreach (var propertyContainerSchema in propertyContainerSchemas) { var property = propertyContainerSchema.Create <PropertySchema>(); var shape = PresentationViewsSubject.GetPresentation(propertyContainerSchema).OfType <CompartmentShape>().FirstOrDefault(); if (shape != null) { var diagramItem = shape.FindDiagramItem <PropertySchema>(p => p.Id == property.Id); if (diagramItem != null) { diagramItems.Add(diagramItem); } } } clientView.Selection.Set(diagramItems); }
public Diagram() { _nodes = new DiagramNodes(this); _edges = new DiagramEdges(this); _selection = new DiagramSelection(this); _itemsInDrawingOrder = new DiagramItemCollection<DiagramItem>(this); _nodes.CollectionChanged += NodeCollectionChanged; _edges.CollectionChanged += EdgeCollectionChanged; _selection.CollectionChanged += SelectionChanged; Background = new SolidColorBrush(Colors.Transparent); _defaultNodeDrawer = new RectangleNodeDrawer(); _defaultEdgeDrawer = new LineEdgeDrawer(); //DefaultLabelDrawer = new BaseLabelDrawer(); _placedItems = new ObservableCollection<IDiagramPlacedItem>(); _placedItems.CollectionChanged += new NotifyCollectionChangedEventHandler(CustomChilren_CollectionChanged); _mouseManager = new DiagramMouseManager(this); _mouseManager.LabelLButtonDblClick += new LabelEventHandler(OnLabelLButtonDblClick); _mouseManager.NodeLButtonDblClick += new NodeEventHandler(OnNodeLButtonDblClick); _mouseManager.EdgeLButtonDblClick += new EdgeEventHandler(OnEdgeLButtonDblClick); _viewport = null; _boundaries = null; CalculateBoundaries(); LockRender = false; LockRecalc = false; _scrollViewer = null; }
/// <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> /// Called by the design surface to allow selection filtering /// </summary> /// <param name="currentSelection">[in] The current selection before any ShapeElements are added or removed.</param> /// <param name="proposedItemsToAdd">[in/out] The proposed DiagramItems to be added to the selection.</param> /// <param name="proposedItemsToRemove">[in/out] The proposed DiagramItems to be removed from the selection.</param> /// <param name="primaryItem"> /// [in/out] The proposed DiagramItem to become the primary DiagramItem of the selection. /// A null value signifies that the last DiagramItem in the resultant selection should be assumed as the /// primary DiagramItem. /// </param> /// <returns> /// true if some or all of the selection was accepted; false if the entire selection proposal /// was rejected. If false, appropriate feedback will be given to the user to indicate that the /// selection was rejected. /// </returns> public override bool GetCompliantSelection( SelectedShapesCollection currentSelection, DiagramItemCollection proposedItemsToAdd, DiagramItemCollection proposedItemsToRemove, DiagramItem primaryItem) { base.GetCompliantSelection(currentSelection, proposedItemsToAdd, proposedItemsToRemove, primaryItem); var originalProposedItemsToAdd = new DiagramItem[proposedItemsToAdd.Count]; proposedItemsToAdd.CopyTo(originalProposedItemsToAdd, 0); // we only perform this with selection rectangles, in which case the focused item will be the diagram // and the user clicks on the "Properties" or "Navigation Properties" compartment on an entity if (currentSelection.FocusedItem != null && currentSelection.FocusedItem.Shape == _diagram) { foreach (var item in originalProposedItemsToAdd) { if (item.Shape != null && item.Shape is ElementListCompartment) { // only perform this if we have selected the "Scalar Properties" ListCompartment or // the "Navigation Properties" ListCompartment var elListCompartment = item.Shape as ElementListCompartment; if (elListCompartment.DefaultCreationDomainClass.Id == ViewModelProperty.DomainClassId || elListCompartment.DefaultCreationDomainClass.Id == ViewModelNavigationProperty.DomainClassId) { // we don't perform this if a Property or NavigationProperty was selected var representedShapeElements = item.RepresentedElements.OfType<ShapeElement>(); if (representedShapeElements.Count() == 1 && representedShapeElements.Contains(item.Shape)) { // find the parent EntityTypeShape that houses this ListCompartment var entityTypeShape = elListCompartment.ParentShape as EntityTypeShape; Debug.Assert( entityTypeShape != null, "Why isn't the parent of the list compartment an EntityTypeShape?"); var entityTypeShapeDiagramItem = new DiagramItem(entityTypeShape); // add the parent EntityTypeShape if it doesn't already exist in the collection if (!currentSelection.Contains(entityTypeShapeDiagramItem) && proposedItemsToAdd.Contains(entityTypeShapeDiagramItem) == false) { proposedItemsToAdd.Add(entityTypeShapeDiagramItem); } proposedItemsToAdd.Remove(item); } } } } } // The code below is responsible to enforce the following diagram items selection rule. (see Multiple Diagram spec). // - if an entity-type-shape is selected, no diagram-item can be selected in the diagram. // - if diagram-item that is not an entity-type-shape is selected, no entity-type-shape can be selected. var firstDiagramItem = FirstSelectionItem(currentSelection, proposedItemsToAdd, proposedItemsToRemove); if (firstDiagramItem != null && proposedItemsToAdd.Count > 0) { var isFirstDiagramItemEntityTypeShape = firstDiagramItem.Shape is EntityTypeShape; // For Multi selection rules, we can only select EntityTypeShapes or else but not both. foreach (var item in proposedItemsToAdd.ToList()) { if (isFirstDiagramItemEntityTypeShape && ((item.Shape is EntityTypeShape) == false)) { RemoveSelectedDiagramItem(item, currentSelection, proposedItemsToAdd, proposedItemsToRemove); } else if (isFirstDiagramItemEntityTypeShape == false && (item.Shape is EntityTypeShape)) { RemoveSelectedDiagramItem(item, currentSelection, proposedItemsToAdd, proposedItemsToRemove); } } } return true; }
/// <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> /// Called when the user selects an item on the diagram. /// Returns the shape that should actually be selected. /// </summary> /// <param name="currentSelection">The pre-existing selection.</param> /// <param name="proposedItemsToAdd">The items that will be selected. Modify this to select something else.</param> /// <param name="proposedItemsToRemove">Items that will be removed from the current selection.</param> /// <param name="primaryItem">The most recent item selected.</param> /// <returns>True if the selection was at least partially successful.</returns> public override bool GetCompliantSelection(SelectedShapesCollection currentSelection, DiagramItemCollection proposedItemsToAdd, DiagramItemCollection proposedItemsToRemove, DiagramItem primaryItem) { // We will modify proposedItemsToAdd, replacing component terminal shapes by component shapes. List <DiagramItem> toAdd = new List <DiagramItem>(); List <DiagramItem> toDrop = new List <DiagramItem>(); foreach (DiagramItem item in proposedItemsToAdd) { if (item.Shape is ComponentTerminalShape) { ComponentTerminal terminal = item.Shape.ModelElement as ComponentTerminal; if (terminal == null) { continue; } toAdd.Add(new DiagramItem(item.Diagram.FindShape(terminal.Component))); toDrop.Add(item); } } proposedItemsToAdd.Remove(toDrop); // Remove the terminals. proposedItemsToAdd.Add(toAdd); // Add the parent components. return(base.GetCompliantSelection(currentSelection, proposedItemsToAdd, proposedItemsToRemove, primaryItem)); }
/// <summary> /// Event Handler when selections in the Diagram are changed. /// When the selection changes in diagram, we build the list of the diagram items that will be emphasized and we ask the diagram item's shapes to be redrawn. /// When the shape is redrawn, each shape determines whether it is in the list; if yes, it will draw the emphasis shape. /// </summary> private void diagramView_OnShapeSelectionChanged(object sender, EventArgs e) { if (ActiveDiagramView != null && ActiveDiagramView.Selection != null) { var shapesToBeEmphasized = new DiagramItemCollection(); var selectedShapes = ActiveDiagramView.Selection; // For each DiagramItem in the Selection // - Get the corresponding model element. // - See if model element implement IContainRelatedElementsToEmphasizeWhenSelected. // - Get related model elements. // - For each related model elements, instantiates DiagramItem for the ModelElement. foreach (DiagramItem diagramItem in selectedShapes) { IContainRelatedElementsToEmphasizeWhenSelected relatedModelElementToEmphasize = null; if (diagramItem.Shape != null && diagramItem.Shape.ModelElement != null) { relatedModelElementToEmphasize = diagramItem.Shape.ModelElement as IContainRelatedElementsToEmphasizeWhenSelected; } else { // DiagramItem.Shape.ModelElement is null when the selected item is not a ShapeElement(for example: Property/NavigationProperty). // Fortunately, we can retrieve the information from RepresentedElements property. relatedModelElementToEmphasize = diagramItem.RepresentedElements.OfType<ModelElement>().FirstOrDefault() as IContainRelatedElementsToEmphasizeWhenSelected; } if (relatedModelElementToEmphasize != null) { // For each ModelElement get the corresponding diagram item. foreach (var emphasizedModelElement in relatedModelElementToEmphasize.RelatedElementsToEmphasizeOnSelected) { DiagramItem emphasizedDiagramItem = null; // if ModelElement is a Property, we could not just instantiate a DiagramItem and pass in the property's PresentationElement to the constructor // since property's PresentationElement is not a ShapeElement. var propertyBase = emphasizedModelElement as ViewModelPropertyBase; if (propertyBase != null) { ViewModelEntityType et = null; var navigationProperty = propertyBase as ViewModelNavigationProperty; var property = propertyBase as ViewModelProperty; if (navigationProperty != null) { et = navigationProperty.EntityType; } else if (property != null) { et = property.EntityType; } else { Debug.Fail("Unexpected property type. Type name:" + propertyBase.GetType().Name); } Debug.Assert(et != null, "Could not get EntityType for property: " + propertyBase.Name); if (et != null) { Debug.Assert( PresentationViewsSubject.GetPresentation(et).Count() <= 1, "There should be at most 1 EntityTypeShape for EntityType:" + et.Name); var ets = PresentationViewsSubject.GetPresentation(et).FirstOrDefault() as EntityTypeShape; emphasizedDiagramItem = ets.GetDiagramItemForProperty(propertyBase); } } else { var relatedPresentationElementToEmphasize = PresentationViewsSubject.GetPresentation(emphasizedModelElement).FirstOrDefault(); if (relatedPresentationElementToEmphasize != null) { var relatedShapeElementToEmphasize = relatedPresentationElementToEmphasize as ShapeElement; if (relatedShapeElementToEmphasize != null) { emphasizedDiagramItem = new DiagramItem(relatedShapeElementToEmphasize); } } } // Only add if the DiagramItem hasn't been added to the list and the diagram item is not a member of selected diagram item list. if (emphasizedDiagramItem != null && shapesToBeEmphasized.Contains(emphasizedDiagramItem) == false && selectedShapes.Contains(emphasizedDiagramItem) == false) { shapesToBeEmphasized.Add(emphasizedDiagramItem); } } } } EmphasizedShapes.Set(shapesToBeEmphasized); } }
/// <summary> /// Returns the first selection item in the provided selection. /// </summary> /// <param name="currentSelection"></param> /// <param name="proposedShapesToAdd"></param> /// <param name="proposedShapesToRemove"></param> /// <returns></returns> private static DiagramItem FirstSelectionItem( SelectedShapesCollection currentSelection, DiagramItemCollection proposedShapesToAdd, DiagramItemCollection proposedShapesToRemove) { // Temporary list that stores what the selections will look like. var actualSelection = new DiagramItemCollection(); // Add current selection items to the list. foreach (DiagramItem item in currentSelection) { if (item != null && actualSelection.Contains(item) == false) { actualSelection.Add(item); } } // Include additional diagram items that will be selected. foreach (var item in proposedShapesToAdd) { if (item != null && actualSelection.Contains(item) == false) { actualSelection.Add(item); } } // Remove diagram items that will be unselected. foreach (var item in proposedShapesToRemove) { if (item != null && actualSelection.Contains(item)) { actualSelection.Remove(item); } } // Return the first item in the list. if (actualSelection.Count > 0) { return actualSelection[0]; } return null; }
/// <summary> /// Helper method to cancel a diagram item to be selected. /// </summary> /// <param name="diagramItem"></param> /// <param name="currentSelection"></param> /// <param name="proposedItemsToAdd"></param> /// <param name="proposedItemsToRemove"></param> private static void RemoveSelectedDiagramItem( DiagramItem diagramItem, SelectedShapesCollection currentSelection, DiagramItemCollection proposedItemsToAdd, DiagramItemCollection proposedItemsToRemove) { if (currentSelection.Contains(diagramItem) == false && proposedItemsToAdd.Contains(diagramItem)) { proposedItemsToAdd.Remove(diagramItem); } if (currentSelection.Contains(diagramItem) && proposedItemsToRemove.Contains(diagramItem) == false) { proposedItemsToRemove.Add(diagramItem); } }