Condividi tramite


Accedere e vincolare la selezione corrente

Quando si scrive un gestore di comandi o movimenti per la lingua specifica del dominio, è possibile determinare quale elemento ha fatto clic con il pulsante destro del mouse sull'utente. È anche possibile impedire l'selezione di alcune forme o campi. Ad esempio, è possibile disporre che quando l'utente fa clic su un elemento Decorator icona, la forma che lo contiene è selezionata. Vincolare la selezione in questo modo riduce il numero di gestori da scrivere. Rende inoltre più semplice per l'utente, che può fare clic in un punto qualsiasi della forma senza dover evitare l'elemento Decorator.

Accedere alla selezione corrente da un gestore comandi

La classe del set di comandi per un linguaggio specifico del dominio contiene i gestori di comandi per i comandi personalizzati. La CommandSet classe da cui deriva la classe del set di comandi per un linguaggio specifico del dominio fornisce alcuni membri per accedere alla selezione corrente.

A seconda del comando, il gestore dei comandi potrebbe richiedere la selezione nella finestra di progettazione modelli, in Esplora modelli o nella finestra attiva.

Per accedere alle informazioni di selezione

  1. La CommandSet classe definisce i membri seguenti che possono essere utilizzati per accedere alla selezione corrente.

    Membro Descrizione
    Metodo IsAnyDocumentSelectionCompartment Restituisce true se uno degli elementi selezionati nella finestra di progettazione modelli è una forma di raggruppamento; in caso contrario, false.
    Metodo IsDiagramSelected Restituisce true se il diagramma è selezionato nella finestra di progettazione modelli; in caso contrario, false.
    Metodo IsSingleDocumentSelection Restituisce true se nella finestra di progettazione modelli è selezionato esattamente un elemento; in caso contrario, false.
    Metodo IsSingleSelection Restituisce true se nella finestra attiva è selezionato esattamente un elemento; in caso contrario, false.
    Proprietà CurrentDocumentSelection Ottiene una raccolta di sola lettura degli elementi selezionati nella finestra di progettazione modelli.
    Proprietà CurrentSelection Ottiene una raccolta di sola lettura degli elementi selezionati nella finestra attiva.
    Proprietà SingleDocumentSelection Ottiene l'elemento primario della selezione nella finestra di progettazione modelli.
    Proprietà SingleSelection Ottiene l'elemento primario della selezione nella finestra attiva.
  2. La CurrentDocView proprietà della CommandSet classe fornisce l'accesso all'oggetto DiagramDocView che rappresenta la finestra di progettazione modelli e fornisce accesso aggiuntivo agli elementi selezionati nella finestra di progettazione modelli.

  3. Inoltre, il codice generato definisce una proprietà della finestra degli strumenti di Esplora risorse e una proprietà di selezione di Explorer nella classe del set di comandi per il linguaggio specifico del dominio.

    • La proprietà della finestra degli strumenti explorer restituisce un'istanza della classe della finestra degli strumenti explorer per il linguaggio specifico del dominio. La classe della ModelExplorerToolWindow finestra degli strumenti explorer deriva dalla classe e rappresenta lo strumento di esplorazione dei modelli per il linguaggio specifico del dominio.

    • La ExplorerSelection proprietà restituisce l'elemento selezionato nella finestra esplora modelli per la lingua specifica del dominio.

Determinare quale finestra è attiva

L'interfaccia IMonitorSelectionService contiene i membri che forniscono l'accesso allo stato di selezione corrente nella shell. È possibile ottenere un IMonitorSelectionService oggetto dalla classe del pacchetto o dalla classe del set di comandi per il linguaggio specifico del dominio tramite la MonitorSelection proprietà definita nella classe base di ognuna. La classe del pacchetto deriva dalla ModelingPackage classe e la classe del set di comandi deriva dalla CommandSet classe .

Per determinare da un gestore comandi quale tipo di finestra è attiva

  1. La MonitorSelection proprietà della CommandSet classe restituisce un IMonitorSelectionService oggetto che fornisce l'accesso allo stato di selezione corrente nella shell.

  2. La CurrentSelectionContainer proprietà dell'interfaccia IMonitorSelectionService ottiene il contenitore di selezione attivo, che può essere diverso dalla finestra attiva.

  3. Aggiungere le proprietà seguenti alla classe del set di comandi per il linguaggio specifico del dominio per determinare il tipo di finestra attiva.

    // 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);
        }
    }
    

Vincolare la selezione

Aggiungendo regole di selezione, è possibile controllare quali elementi vengono selezionati quando l'utente seleziona un elemento nel modello. Ad esempio, per consentire all'utente di considerare un numero di elementi come una singola unità, è possibile usare una regola di selezione.

Per creare una regola di selezione

  1. Creare un file di codice personalizzato nel progetto DSL

  2. Definire una classe di regole di selezione derivata dalla DiagramSelectionRules classe .

  3. Eseguire l'override del GetCompliantSelection metodo della classe della regola di selezione per applicare i criteri di selezione.

  4. Aggiungere una definizione di classe parziale per la classe ClassDiagram al file di codice personalizzato.

    La ClassDiagram classe deriva dalla Diagram classe ed è definita nel file di codice generato, Diagram.cs, nel progetto DSL.

  5. Eseguire l'override della SelectionRules proprietà della ClassDiagram classe per restituire la regola di selezione personalizzata.

    L'implementazione predefinita della SelectionRules proprietà ottiene un oggetto regola di selezione che non modifica la selezione.

Esempio

Il file di codice seguente crea una regola di selezione che espande la selezione in modo da includere tutte le istanze di ognuna delle forme di dominio selezionate inizialmente.

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;
                }
            }
        }
    }
}