다음을 통해 공유


현재 선택 항목 액세스 및 제약

DSL(Domain-Specific Language)에 대한 명령 또는 제스처 처리기를 작성할 때 사용자가 마우스 오른쪽 단추로 클릭한 요소를 확인할 수 있습니다. 일부 도형이나 필드가 선택되지 않도록 방지할 수도 있습니다. 예를 들어 사용자가 아이콘 데코레이터를 클릭할 때 아이콘 데코레이터를 포함하는 도형이 대신 선택되게 정렬할 수 있습니다. 이러한 방식으로 선택을 제한하면 작성해야 하는 처리기의 수가 줄어듭니다. 또한 데코레이터를 피하지 않고도 도형의 아무 곳이나 클릭할 수 있어 사용하기가 더 쉽습니다.

명령 처리기에서 현재 선택 항목에 액세스

DSL(Domain-Specific Language)에 대한 명령 집합 클래스에는 사용자 지정 명령에 대한 명령 처리기가 포함되어 있습니다. DSL(Domain-Specific Language)에 대한 명령 집합 클래스가 파생되는 CommandSet 클래스는 현재 선택 항목에 액세스하기 위한 몇 가지 멤버를 제공합니다.

명령에 따라 명령 처리기에는 모델 디자이너, 모델 탐색기 또는 활성 창의 선택 영역이 필요할 수 있습니다.

선택 정보에 액세스

  1. CommandSet 클래스는 현재 선택 영역에 액세스하는 데 사용할 수 있는 다음 멤버를 정의합니다.

    멤버 설명
    IsAnyDocumentSelectionCompartment 메서드 모델 디자이너에서 선택한 요소가 구획 도형이면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
    IsDiagramSelected 메서드 모델 디자이너에서 다이어그램이 선택되어 있으면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
    IsSingleDocumentSelection 메서드 모델 디자이너에서 정확히 하나의 요소가 선택되어 있으면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
    IsSingleSelection 메서드 활성 창에서 정확히 하나의 요소가 선택되어 있으면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
    CurrentDocumentSelection 속성 모델 디자이너에서 선택한 요소의 읽기 전용 컬렉션을 가져옵니다.
    CurrentSelection 속성 활성 창에서 선택한 요소의 읽기 전용 컬렉션을 가져옵니다.
    SingleDocumentSelection 속성 모델 디자이너에서 선택 영역의 기본 요소를 가져옵니다.
    SingleSelection 속성 활성 창에서 선택 영역의 기본 요소를 가져옵니다.
  2. CommandSet 클래스의 CurrentDocView 속성은 모델 디자이너 창을 나타내는 DiagramDocView 개체에 대한 액세스를 제공하며 모델 디자이너에서 선택된 요소에 대한 추가적인 액세스도 제공합니다.

  3. 또한 생성된 코드는 DSL(Domain-Specific Language)에 대한 명령 집합 클래스에서 탐색기 도구 창 속성 및 탐색기 선택 속성을 정의합니다.

    • 탐색기 도구 창 속성은 DSL(Domain-Specific Language)에 대한 탐색기 도구 창 클래스의 인스턴스를 반환합니다. 탐색기 도구 창 클래스는 ModelExplorerToolWindow 클래스에서 파생되며 DSL(Domain-Specific Language)에 대한 모델 탐색기를 나타냅니다.

    • ExplorerSelection 속성은 DSL(Domain-Specific Language)에 대한 모델 탐색기 창에서 선택한 요소를 반환합니다.

활성 상태인 창 확인

IMonitorSelectionService 인터페이스는 셸의 현재 선택 상태에 대한 액세스를 제공하는 멤버를 정의합니다. 각각의 기본 클래스에 정의되어 있는 MonitorSelection 속성을 통해 DSL(Domain-Specific Language)에 대한 명령 집합 클래스 또는 패키지 클래스에서 IMonitorSelectionService 개체를 가져올 수 있습니다. 패키지 클래스는 ModelingPackage 클래스에서 파생되고 명령 집합 클래스는 CommandSet 클래스에서 파생됩니다.

명령 처리기에서 활성 상태인 창 유형을 확인하려면

  1. CommandSet 클래스의 MonitorSelection 속성은 셸의 현재 선택 영역 상태에 대한 액세스를 제공하는 IMonitorSelectionService 개체를 반환합니다.

  2. IMonitorSelectionService 인터페이스의 CurrentSelectionContainer 속성은 활성 선택 영역 컨테이너를 가져오며, 이는 활성 창과 다를 수 있습니다.

  3. 활성 상태인 창 유형을 확인하려면 DSL(Domain-Specific Language)에 대한 명령 집합 클래스에 다음 속성을 추가합니다.

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

선택 영역 제한

선택 규칙을 추가하면 사용자가 모델에서 요소를 선택할 때 선택되는 요소를 제어할 수 있습니다. 예를 들어 사용자가 여러 요소를 하나의 단위로 처리할 수 있도록 하려면 선택 영역 규칙을 사용하면 됩니다.

선택 규칙을 만들려면

  1. DSL 프로젝트에 사용자 지정 코드 파일을 만듭니다.

  2. DiagramSelectionRules 클래스에서 파생된 선택 영역 규칙 클래스를 정의합니다.

  3. 선택 영역 조건을 적용하려면 선택 영역 규칙 클래스의 GetCompliantSelection 메서드를 재정의합니다.

  4. ClassDiagram 클래스에 대한 부분적 클래스 정의를 사용자 지정 코드 파일에 추가합니다.

    ClassDiagram 클래스는 Diagram 클래스에서 파생되며 DSL 프로젝트에서 생성된 코드 파일 Diagram.cs에 정의됩니다.

  5. 사용자 지정 선택 영역 규칙을 반환하려면 ClassDiagram 클래스의 SelectionRules 속성을 재정의합니다.

    SelectionRules 속성의 기본 구현은 선택 영역을 수정하지 않는 선택 영역 규칙 개체를 가져옵니다.

예시

다음 코드 파일은 처음에 선택된 각 도메인 도형의 모든 인스턴스를 포함하도록 선택 영역을 확장하는 선택 영역 규칙을 만듭니다.

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