Compartilhar via


Acessar e restringir a seleção atual

Ao gravar um manipulador de comandos ou gestos para sua linguagem específica de domínio, você pode determinar em qual elemento o usuário clicou com o botão direito do mouse. Você também pode impedir que algumas formas ou campos sejam selecionados. Por exemplo, você pode determinar que, quando o usuário clica em um decorador de ícone, a forma que a contém é selecionada. A restrição da seleção dessa maneira reduz o número de manipuladores que você precisa gravar. Isso também facilita para o usuário, que pode clicar em qualquer lugar da forma sem precisar evitar o decorador.

Acessar a seleção atual de um manipulador de comandos

A classe de conjunto de comandos para uma linguagem específica de domínio contém os manipuladores de comando para seus comandos personalizados. A classe CommandSet, da qual a classe de conjunto de comandos para uma linguagem específica de domínio deriva, fornece alguns membros para acessar a seleção atual.

Dependendo do comando, o manipulador de comandos pode precisar da seleção no designer de modelo, no gerenciador de modelos ou na janela ativa.

Para acessar as informações de seleção

  1. A classe CommandSet define os membros a seguir que podem ser usados para acessar a seleção atual.

    Membro Descrição
    Método IsAnyDocumentSelectionCompartment Retorna true se qualquer um dos elementos selecionados no designer de modelo for uma forma de compartimento. Caso contrário, false.
    Método IsDiagramSelected Retorna true se o diagrama estiver selecionado no designer de modelo. Caso contrário, false.
    Método IsSingleDocumentSelection Retorna true se exatamente um elemento estiver selecionado no designer de modelo. Caso contrário, false.
    Método IsSingleSelection Retorna true se exatamente um elemento estiver selecionado na janela ativa. Caso contrário, false.
    Propriedade CurrentDocumentSelection Obtém uma coleção somente leitura dos elementos selecionados no designer de modelo.
    Propriedade CurrentSelection Obtém uma coleção somente leitura dos elementos selecionados na janela ativa.
    Propriedade SingleDocumentSelection Obtém o elemento primário da seleção no designer de modelo.
    Propriedade SingleSelection Obtém o elemento primário da seleção na janela ativa.
  2. A propriedade CurrentDocView da classe CommandSet fornece acesso ao objeto DiagramDocView que representa a janela do designer de modelo e fornece acesso adicional aos elementos selecionados no designer de modelo.

  3. Além disso, o código gerado define uma propriedade de janela de ferramentas do explorador e uma propriedade de seleção do explorador na classe de conjunto de comandos para a linguagem específica de domínio.

    • A propriedade da janela de ferramentas do explorador retorna uma instância da classe de janela de ferramentas do explorador para a linguagem específica de domínio. A classe da janela de ferramentas do explorador deriva da classe ModelExplorerToolWindow e representa o explorador de modelos para a linguagem específica de domínio.

    • A propriedade ExplorerSelection retorna o elemento selecionado na janela do explorador de modelos para a linguagem específica de domínio.

Determinar qual janela está ativa

A interface IMonitorSelectionService contém membros que fornecem acesso ao estado de seleção atual no shell. Você pode obter um objeto IMonitorSelectionService da classe de pacote ou da classe de conjunto de comandos para a linguagem específica de domínio por meio da propriedade MonitorSelection definida na classe base de cada um. A classe do pacote deriva da classe ModelingPackage e a classe do conjunto de comandos deriva da classe CommandSet.

Para determinar de um manipulador de comandos qual tipo de janela está ativa

  1. A propriedade MonitorSelection da classe CommandSet retorna um objeto IMonitorSelectionService que fornece acesso ao estado de seleção atual no shell.

  2. A propriedade CurrentSelectionContainer da interface IMonitorSelectionService obtém o contêiner de seleção ativo, que pode ser diferente da janela ativa.

  3. Adicione as propriedades a seguir à classe de conjunto de comandos para sua linguagem específica de domínio para determinar qual tipo de janela está ativa.

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

Restringir a Seleção

Ao adicionar regras de seleção, você pode controlar quais elementos são selecionados quando o usuário seleciona um elemento no modelo. Por exemplo, para permitir que o usuário trate vários elementos como uma única unidade, você pode usar uma regra de seleção.

Para criar uma regra de seleção

  1. Criar um arquivo de código personalizado no projeto DSL

  2. Defina uma classe da regra de seleção derivada da classe DiagramSelectionRules.

  3. Substitua o método GetCompliantSelection da classe da regra de seleção para aplicar os critérios de seleção.

  4. Adicione uma definição de classe parcial para a classe ClassDiagram ao arquivo de código personalizado.

    A classe ClassDiagram deriva da classe Diagram e é definida no arquivo de código gerado, Diagram.cs, no projeto DSL.

  5. Substitua a propriedade SelectionRules da classe ClassDiagram para retornar a regra de seleção personalizada.

    A implementação padrão da propriedade SelectionRules obtém um objeto da regra de seleção que não modifica a seleção.

Exemplo

O arquivo de código a seguir cria uma regra de seleção que expande a seleção para incluir todas as instâncias de cada forma de domínio selecionada inicialmente.

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