Partager via


Accéder à la sélection actuelle pour la contraindre

Lorsque vous écrivez un gestionnaire de commandes ou de mouvements pour votre langage spécifique au domaine, vous pouvez déterminer l’élément sur lequel l’utilisateur a cliqué avec le bouton droit. Vous pouvez également empêcher la sélection de certaines formes ou certains champs. Par exemple, vous pouvez faire en sorte que lorsque l’utilisateur clique sur un décorateur d’icône, la forme qui le contient est sélectionnée à la place. Contraindre la sélection de cette manière réduit le nombre de gestionnaires que vous devez écrire. Cela facilite également la tâche de l’utilisateur, qui peut cliquer n’importe où dans la forme sans avoir à éviter le décorateur.

Accéder à la sélection actuelle à partir d’un gestionnaire de commandes

La classe de jeu de commandes pour un langage spécifique à un domaine contient les gestionnaires de commandes pour vos commandes personnalisées. La classe CommandSet, à partir de laquelle la classe de jeu de commandes pour un langage spécifique au domaine dérive, fournit quelques membres pour accéder à la sélection actuelle.

Selon la commande, le gestionnaire de commandes peut avoir besoin de la sélection dans le concepteur de modèles, l’explorateur de modèles ou la fenêtre active.

Pour accéder aux informations de sélection

  1. La classe CommandSet définit les membres suivants qui peuvent être utilisés pour accéder à la sélection actuelle.

    Membre Description
    Méthode IsAnyDocumentSelectionCompartment Retourne true si l’un des éléments sélectionnés dans le concepteur de modèles est une forme de compartiment ; sinon, false.
    Méthode IsDiagramSelected Retourne true si le diagramme est sélectionné dans le concepteur de modèles ; sinon, false.
    Méthode IsSingleDocumentSelection Retourne true si exactement un élément est sélectionné dans le concepteur de modèles ; sinon, false.
    Méthode IsSingleSelection Retourne true si exactement un élément est sélectionné dans la fenêtre active ; sinon, false.
    Propriété CurrentDocumentSelection Obtient une collection en lecture seule des éléments sélectionnés dans le concepteur de modèles.
    Propriété CurrentSelection Obtient une collection en lecture seule des éléments sélectionnés dans la fenêtre active.
    Propriété SingleDocumentSelection Obtient l’élément principal de la sélection dans le concepteur de modèles.
    Propriété SingleSelection Obtient l’élément principal de la sélection dans la fenêtre active.
  2. La propriété CurrentDocView de la classe CommandSet permet d’accéder à l’objet DiagramDocView qui représente la fenêtre du concepteur de modèles et fournit un accès supplémentaire aux éléments sélectionnés dans le concepteur de modèles.

  3. En outre, le code généré définit une propriété de fenêtre de l’outil d’explorateur et une propriété de sélection d’explorateur dans la classe de jeu de commandes pour le langage spécifique au domaine.

    • La propriété de la fenêtre de l’outil d’explorateur retourne une instance de la classe de fenêtre d’outil d’explorateur pour le langage spécifique au domaine. La classe de fenêtre de l’outil Explorateur dérive de la classe ModelExplorerToolWindow et représente l’Explorateur de modèles pour le langage spécifique au domaine.

    • La propriété ExplorerSelection retourne l’élément sélectionné dans la fenêtre de l’Explorateur de modèles pour le langage spécifique au domaine.

Déterminer la fenêtre active

L’interface IMonitorSelectionService contient des définitions de membres qui fournissent l’accès à l’état de sélection actuel dans l’interpréteur de commandes. Vous pouvez obtenir un objet IMonitorSelectionService à partir de la classe de package ou de la classe de jeu de commandes pour le langage spécifique au domaine via la propriété MonitorSelection définie dans la classe de base de chaque élément. La classe de package dérive de la classe ModelingPackage, et la classe de jeu de commandes dérive de la classe CommandSet.

Pour déterminer à partir d’un gestionnaire de commandes quel type de fenêtre est actif

  1. La propriété MonitorSelection de la classe CommandSet retourne un objet IMonitorSelectionService qui fournit l’accès à l’état de sélection actuel dans l’interpréteur de commandes.

  2. La propriété CurrentSelectionContainer de l’interface IMonitorSelectionService obtient le conteneur de sélection actif, qui peut être différent de la fenêtre active.

  3. Ajoutez les propriétés suivantes à la classe de jeu de commandes pour votre langage spécifique au domaine afin de déterminer quel type de fenêtre est actif.

    // using Microsoft.VisualStudio.Modeling.Shell;
    
    // Returns true if the model designer is the active selection container;
    // otherwise, false.
    protected bool IsDesignerActive
    {
        get
        {
            return (this.MonitorSelection.CurrentSelectionContainer
                is DiagramDocView);
        }
    }
    
    // Returns true if the model explorer is the active selection container;
    // otherwise, false.
    protected bool IsExplorerActive
    {
        get
        {
            return (this.MonitorSelection.CurrentSelectionContainer
                is ModelExplorerToolWindow);
        }
    }
    

Limiter la sélection

En ajoutant des règles de sélection, vous pouvez contrôler les éléments sélectionnés lorsque l’utilisateur sélectionne un élément dans le modèle. Par exemple, pour permettre à l’utilisateur de traiter un certain nombre d’éléments comme une seule unité, vous pouvez utiliser une règle de sélection.

Pour créer une règle de sélection

  1. Créer un fichier de code personnalisé dans le projet DSL

  2. Définissez une classe de règle de sélection dérivée de la classe DiagramSelectionRules.

  3. Remplacez la méthode GetCompliantSelection de la classe de règle de sélection pour appliquer les critères de sélection.

  4. Ajoutez une définition de classe partielle pour la classe ClassDiagram à votre fichier de code personnalisé.

    La classe ClassDiagram dérive de la classe Diagram et est définie dans le fichier de code généré, Diagram.cs, dans le projet DSL.

  5. Remplacez la propriété SelectionRules de la classe ClassDiagram pour retourner la règle de sélection personnalisée.

    L’implémentation par défaut de la propriété SelectionRules obtient un objet de règle de sélection qui ne modifie pas la sélection.

Exemple

Le fichier de code suivant crée une règle de sélection qui développe la sélection pour inclure toutes les instances de chacune des formes de domaine initialement sélectionnées.

using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;

namespace CompanyName.ProductName.GroupingDsl
{
    public class CustomSelectionRules : DiagramSelectionRules
    {
        protected Diagram diagram;
        protected IElementDirectory elementDirectory;

        public CustomSelectionRules(Diagram diagram)
        {
            if (diagram == null) throw new ArgumentNullException();

            this.diagram = diagram;
            this.elementDirectory = diagram.Store.ElementDirectory;
        }

        /// <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)
        {
            if (currentSelection.Count == 0 && proposedItemsToAdd.Count == 0) return true;

            HashSet<DomainClassInfo> itemsToAdd = new HashSet<DomainClassInfo>();

            foreach (DiagramItem item in proposedItemsToAdd)
            {
                if (item.Shape != null)
                    itemsToAdd.Add(item.Shape.GetDomainClass());
            }
            proposedItemsToAdd.Clear();
            foreach (DomainClassInfo classInfo in itemsToAdd)
            {
                foreach (ModelElement element
                    in this.elementDirectory.FindElements(classInfo, false))
                {
                    if (element is ShapeElement)
                    {
                        proposedItemsToAdd.Add(
                            new DiagramItem((ShapeElement)element));
                    }
                }
            }

            return true;
        }
    }

    public partial class ClassDiagram
    {
        protected CustomSelectionRules customSelectionRules = null;

        protected bool multipleSelectionMode = true;

        public override DiagramSelectionRules SelectionRules
        {
            get
            {
                if (multipleSelectionMode)
                {
                    if (customSelectionRules == null)
                    {
                        customSelectionRules = new CustomSelectionRules(this);
                    }
                    return customSelectionRules;
                }
                else
                {
                    return base.SelectionRules;
                }
            }
        }
    }
}