Udostępnij za pośrednictwem


Ograniczanie bieżącego wyboru i uzyskiwanie dostępu do niego

Podczas pisania programu obsługi poleceń lub gestów dla języka specyficznego dla domeny można określić, który element użytkownik kliknął prawym przyciskiem myszy. Można również uniemożliwić zaznaczanie niektórych kształtów lub pól. Można na przykład rozmieścić, że gdy użytkownik kliknie ikonę dekoratora, zamiast tego zostanie wybrany kształt, który go zawiera. Ograniczenie zaznaczenia w ten sposób zmniejsza liczbę procedur obsługi, które należy zapisać. Ułatwia to również użytkownikowi kliknięcie w dowolnym miejscu kształtu bez konieczności unikania dekoratora.

Uzyskiwanie dostępu do bieżącego zaznaczenia z programu obsługi poleceń

Klasa zestawu poleceń dla języka specyficznego dla domeny zawiera programy obsługi poleceń dla poleceń niestandardowych. Klasa CommandSet , z której pochodzi klasa zestawu poleceń dla języka specyficznego dla domeny, udostępnia kilka elementów członkowskich do uzyskiwania dostępu do bieżącego zaznaczenia.

W zależności od polecenia program obsługi poleceń może wymagać wyboru w projektancie modeli, eksploratorze modeli lub aktywnym oknie.

Aby uzyskać dostęp do informacji o wyborze

  1. Klasa CommandSet definiuje następujące elementy członkowskie, których można użyć do uzyskania dostępu do bieżącego zaznaczenia.

    Element członkowski opis
    IsAnyDocumentSelectionCompartment Metoda Zwraca true wartość, jeśli którykolwiek z elementów wybranych w projektancie modelu jest kształtem przedziału; w przeciwnym razie false.
    IsDiagramSelected Metoda Zwraca true wartość , jeśli diagram został wybrany w projektancie modelu; w przeciwnym razie false.
    IsSingleDocumentSelection Metoda Zwraca true , jeśli w projektancie modelu wybrano dokładnie jeden element; w przeciwnym razie false.
    IsSingleSelection Metoda Zwraca true , jeśli w aktywnym oknie wybrano dokładnie jeden element; w przeciwnym razie false.
    CurrentDocumentSelection Właściwość Pobiera kolekcję elementów wybranych w projektancie modeli tylko do odczytu.
    CurrentSelection Właściwość Pobiera kolekcję elementów wybranych w aktywnym oknie tylko do odczytu.
    SingleDocumentSelection Właściwość Pobiera podstawowy element zaznaczenia w projektancie modelu.
    SingleSelection Właściwość Pobiera podstawowy element zaznaczenia w aktywnym oknie.
  2. Właściwość CurrentDocView CommandSet klasy zapewnia dostęp do DiagramDocView obiektu reprezentującego okno projektanta modelu i zapewnia dodatkowy dostęp do wybranych elementów w projektancie modelu.

  3. Ponadto wygenerowany kod definiuje właściwość okna narzędzi eksploratora i właściwość wyboru eksploratora w klasie zestawu poleceń dla języka specyficznego dla domeny.

    • Właściwość okna narzędzi eksploratora zwraca wystąpienie klasy okna narzędzi eksploratora dla języka specyficznego dla domeny. Klasa okna narzędzi eksploratora pochodzi z ModelExplorerToolWindow klasy i reprezentuje eksploratora modeli dla języka specyficznego dla domeny.

    • Właściwość ExplorerSelection zwraca wybrany element w oknie eksploratora modelu dla języka specyficznego dla domeny.

Określanie, które okno jest aktywne

Interfejs IMonitorSelectionService zawiera definicje elementów członkowskich, które zapewniają dostęp do bieżącego stanu zaznaczenia w powłoce. Obiekt można pobrać IMonitorSelectionService z klasy pakietu lub klasy zestawu poleceń dla języka specyficznego dla domeny za pomocą MonitorSelection właściwości zdefiniowanej w klasie bazowej każdego z nich. Klasa pakietu pochodzi z ModelingPackage klasy, a klasa zestawu poleceń pochodzi z CommandSet klasy .

Aby określić z programu obsługi poleceń, jaki typ okna jest aktywny

  1. Właściwość MonitorSelection CommandSet klasy zwraca IMonitorSelectionService obiekt, który zapewnia dostęp do bieżącego stanu zaznaczenia w powłoce.

  2. Właściwość CurrentSelectionContainer interfejsu IMonitorSelectionService pobiera aktywny kontener wyboru, który może różnić się od aktywnego okna.

  3. Dodaj następujące właściwości do klasy zestawu poleceń dla języka specyficznego dla domeny, aby określić, jakiego typu okno jest aktywne.

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

Ogranicz zaznaczenie

Dodając reguły wyboru, można kontrolować, które elementy są wybrane, gdy użytkownik wybierze element w modelu. Aby na przykład umożliwić użytkownikowi traktowanie wielu elementów jako pojedynczej jednostki, możesz użyć reguły wyboru.

Aby utworzyć regułę wyboru

  1. Tworzenie niestandardowego pliku kodu w projekcie DSL

  2. Zdefiniuj klasę reguły wyboru, która pochodzi z DiagramSelectionRules klasy .

  3. Zastąpi metodę GetCompliantSelection klasy reguł wyboru, aby zastosować kryteria wyboru.

  4. Dodaj definicję klasy częściowej dla klasy ClassDiagram do niestandardowego pliku kodu.

    Klasa ClassDiagram pochodzi z Diagram klasy i jest zdefiniowana w wygenerowanych plikach kodu Diagram.cs w projekcie DSL.

  5. Zastąpi SelectionRules właściwość ClassDiagram klasy, aby zwrócić niestandardową regułę wyboru.

    Domyślna implementacja SelectionRules właściwości pobiera obiekt reguły wyboru, który nie modyfikuje zaznaczenia.

Przykład

Poniższy plik kodu tworzy regułę wyboru, która rozszerza zaznaczenie, aby uwzględnić wszystkie wystąpienia każdego z kształtów domeny, które zostały początkowo wybrane.

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