コード例 #1
0
        /// <summary>
        /// Called on copy, cut or drag.
        /// For a copy or cut, the supplied elements are the model elements, and the call comes, via AddGroupFormat, from ClipboardCommands.ProcessOnMenuCopy().
        /// For a drag operation, the elements are the selected shapes and connectors, and the call comes from Diagram.DoDragDrop, if CanMove or CanCopy are true.
        /// In the drag case, we want to add the model elements so that we can do a copy
        /// if the user presses CTRL while dragging.
        ///
        /// See http://msdn.microsoft.com/library/ff521398.aspx
        /// </summary>
        /// <param name="shapeOrModelElements">The shape or model elements being copied - usually the current selection.</param>
        /// <param name="closureType">Copy or Delete</param>
        /// <returns>Group to be stored in the clipboard.</returns>
        protected override ElementGroup CreateElementGroup(ICollection <ModelElement> shapeOrModelElements, ClosureType closureType)
        {
            // CreateElementGroup respects the settings of PropagateCopy.
            // Notice that we have set PropagateCopy on the roles from components to the terminals,
            // so that terminals will always be copied along with their parents.

            // Add the specified group of shapes or elements:
            ElementGroup group = base.CreateElementGroup(shapeOrModelElements, closureType);

            // If this a set of shapes, add their model elements:
            if (shapeOrModelElements.FirstOrDefault() is PresentationElement)
            {
                // Get the model elements of the shapes:
                ICollection <ModelElement> modelElements =
                    shapeOrModelElements.OfType <PresentationElement>()
                    // Filter out shapes such as labels that don't have model elements:
                    .Where(pel => pel.ModelElement != null)
                    .Select(pel => pel.ModelElement).ToList();

                ElementGroup melGroup = base.CreateElementGroup(modelElements, closureType);
                group.AddRange(melGroup.GetElements());
            }

            return(group);

            // 2011-03-21 Thanks to Joeul in VMSDK Forum for a bug fix here.
            // http://social.msdn.microsoft.com/Forums/en-US/dslvsarchx/thread/0b0b16d4-6014-4b35-9e5a-e27ea02e0ee3
        }
コード例 #2
0
        /* There are two versions of CreateElementToolPrototype here.
         * One deals with each Component subtype separately: if you add a new subtype, you need to add more here.
         * The other automatically deals with eacn Component subtype, using DSL reflection info.
         *
         * See http://msdn.microsoft.com/library/bb126279.aspx#groups
         */

        /*
         * /// <summary>
         * /// Toolbox initialization, called for each element tool on the toolbox.
         * /// This version deals with each Component subtype separately.
         * /// </summary>
         * /// <param name="store"></param>
         * /// <param name="domainClassId">Identifies the domain class this tool should instantiate.</param>
         * /// <returns>prototype of the object or group of objects to be created by tool</returns>
         * protected override ElementGroupPrototype CreateElementToolPrototype(Store store, Guid domainClassId)
         * {
         *
         *  if (domainClassId == Resistor.DomainClassId)
         *  {
         *      Resistor resistor = new Resistor(store);
         *
         *      // Must initialize these in order of initialization:
         *      // DSLT v1 bug affecting derived relationships.
         *      resistor.T1 = new ComponentTerminal(store);
         *      resistor.T2 = new ComponentTerminal(store);
         *
         *      resistor.T1.Name = "t1";
         *      resistor.T2.Name = "t2";
         *
         *      ElementGroup elementGroup = new ElementGroup(store.DefaultPartition);
         *      elementGroup.AddGraph(resistor, true);
         *      // AddGraph includes the embedded parts.
         *
         *      return elementGroup.CreatePrototype();
         *  }
         *  else if (domainClassId == Capacitor.DomainClassId)
         *  {
         *      Capacitor capacitor = new Capacitor(store);
         *
         *      // Must initialize these in order of initialization:
         *      // DSLT v1 bug affecting derived relationships.
         *      capacitor.T1 = new ComponentTerminal(store);
         *      capacitor.T2 = new ComponentTerminal(store);
         *
         *      capacitor.T1.Name = "t1";
         *      capacitor.T2.Name = "t2";
         *
         *      ElementGroup elementGroup = new ElementGroup(store.DefaultPartition);
         *      elementGroup.AddGraph(capacitor, true);
         *      // AddGraph includes the embedded parts.
         *
         *      return elementGroup.CreatePrototype();
         *  }
         *
         *  else if (domainClassId == Transistor.DomainClassId)
         *  {
         *      Transistor transistor = new Transistor(store);
         *
         *      // Must initialize these in order of initialization:
         *      // DSLT v1 bug affecting derived relationships.
         *      transistor.Base = new ComponentTerminal(store);
         *      transistor.Collector = new ComponentTerminal(store);
         *      transistor.Emitter = new ComponentTerminal(store);
         *
         *      transistor.Base.Name = "base";
         *      transistor.Collector.Name = "collector";
         *      transistor.Emitter.Name = "emitter";
         *
         *      // Create an ElementGroup for the Toolbox.
         *      ElementGroup elementGroup = new ElementGroup(store.DefaultPartition);
         *      elementGroup.AddGraph(transistor, true);
         *      // AddGraph includes the embedded parts
         *
         *      return elementGroup.CreatePrototype();
         *  }
         *
         *  else
         *  {
         *      return base.CreateElementToolPrototype(store, domainClassId);
         *  }
         *
         *
         * }
         *
         */

        /// <summary>
        /// Toolbox initialization for components with fixed embedded parts.
        /// This deals with all the subclasses of Component, adding an instance for each relationship derived from ComponentHasTerminals.
        /// The benefit of this approach is that it does not need to be adjusted for each new Component subclass.
        /// Called for each element tool on the toolbox.
        /// </summary>
        /// <param name="store"></param>
        /// <param name="domainClassId">Identifies the domain class this tool should instantiate.</param>
        /// <returns>prototype of the object or group of objects to be created by tool</returns>
        protected override ElementGroupPrototype CreateElementToolPrototype(Store store, Guid domainClassId)
        {
            // Called for each element tool on the toolbox.
            // Get the class meta info for this class.
            DomainClassInfo thisClassInfo = store.DomainDataDirectory.FindDomainClass(domainClassId);

            if (!thisClassInfo.IsDerivedFrom(Component.DomainClassId))
            {
                // Not one of those we're interested in: defer to base method.
                return(base.CreateElementToolPrototype(store, domainClassId));
            }
            else
            {
                // Construct an instance of this type. Use the constructor that takes a store and a variable number of property bindings.
                Component component = (Component)thisClassInfo.ImplementationClass. // get the actual class from the meta info
                                      InvokeMember(                                 // method in System.Reflection.Type
                    "",
                    System.Reflection.BindingFlags.CreateInstance                   // invoke the constructor
                    | System.Reflection.BindingFlags.OptionalParamBinding,          // which has a params binding
                    null,                                                           // no special binder
                    null,                                                           //no target object since we want the constructor
                    new object[] { store });                                        // Called like "new Resistor(store)"

                // Now add whatever ComponentTerminals it has.
                // Each Component subtype sources several subrelationships of ComponentHasComponentTerminal.
                // Go through the metainfo about each role the class plays in relationships.
                foreach (DomainRoleInfo role in thisClassInfo.LocalDomainRolesPlayed)
                {
                    // Pick out the roles that are one end of a relationship to a Terminal.
                    if (role.DomainRelationship.IsDerivedFrom(ComponentHasComponentTerminal.DomainClassId) &&
                        !role.DomainRelationship.ImplementationClass.IsAbstract)
                    {
                        ComponentTerminal terminal = new ComponentTerminal(store);
                        // Fill in the instance name with the name of the role - just a convenience.
                        // The role at the Terminal end of the relationship is the one called "T1" or "collector" or some such.
                        terminal.Name = role.OppositeDomainRole.Name.ToLowerInvariant();
                        // Instantiate the relationship with the constructor that takes the component and terminal.
                        role.DomainRelationship.ImplementationClass.InvokeMember("", System.Reflection.BindingFlags.CreateInstance,
                                                                                 null, null,
                                                                                 new object[] { component, terminal });
                    }
                }
                // Create an Element Group Prototype containing this tree.
                ElementGroup elementGroup = new ElementGroup(store.DefaultPartition);
                elementGroup.AddGraph(component, true, true); // AddGraph includes the embedded elements.
                elementGroup.AddRange(component.ComponentTerminals, true);
                ElementGroupPrototype egp = elementGroup.CreatePrototype();
                return(egp);
            }
        }
コード例 #3
0
        /// <summary>
        /// Create an EGP to add to the clipboard.
        /// Called when the elements to be copied or dragged have been
        /// collected into an ElementGroup and after the roots have been marked.
        /// This override ensures that the shapes and connectors of each element and relationship are included.
        /// </summary>
        /// <param name="elementGroup">Group of elements and maybe shapes</param>
        /// <param name="elements">The original set of elements to be added, not including children, relationships, etc. Typically, the current selection.</param>
        /// <param name="closureType">Copy or Delete - specifies which propagation scheme to follow</param>
        /// <returns>EGP </returns>
        protected override ElementGroupPrototype CreateElementGroupPrototype(ElementGroup elementGroup, ICollection <ModelElement> elements, ClosureType closureType)
        {
            // Get the elements already in the group:
            ModelElement[] mels = elementGroup.ModelElements
                                  .Concat(elementGroup.ElementLinks) // Omit if the paste target is not the diagram.
                                  .ToArray();

            // Get their shapes and connectors:
            IEnumerable <PresentationElement> shapes =
                mels.SelectMany(mel =>
                                PresentationViewsSubject.GetPresentation(mel));

            elementGroup.AddRange(shapes, true);

            return(base.CreateElementGroupPrototype(elementGroup, elements, closureType));
        }