다음을 통해 공유


모양 및 연결선을 업데이트하여 모델 반영

Visual Studio의 도메인 특정 언어에서 도형의 모양이 기본 모델의 상태를 반영하도록 할 수 있습니다.

이 항목의 코드 예제를 Dsl 프로젝트의 .cs 파일에 추가해야 합니다. 각 파일에 다음 지시문이 필요합니다.

using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;

데코레이터 표시 여부를 제어하는 도형 맵 속성 설정

DSL 정의에서 도형과 도메인 클래스 간의 매핑을 구성하면 프로그램 코드를 작성하지 않고도 데코레이터의 표시 여부를 제어할 수 있습니다. 자세한 내용은 DSL을 정의하는 방법을 참조하세요.

도형의 색 및 스타일을 속성으로 노출

DSL 정의에서 도형 클래스를 마우스 오른쪽 단추로 클릭하고 노출 추가를 가리킨 다음 채우기 색과 같은 항목 중 하나를 클릭합니다.

이제 모양에는 프로그램 코드에서 설정하거나 사용자로 설정할 수 있는 도메인 속성이 있습니다. 예를 들어 명령 또는 규칙의 프로그램 코드에서 이를 설정하려면 다음을 작성할 수 있습니다.

shape.FillColor = System.Drawing.Color.Red;

사용자가 아니라 프로그램 제어에서만 속성 변수를 만들려는 경우 DSL 정의 다이어그램에서 채우기 색과 같은 새 도메인 속성을 선택합니다. 그런 다음 속성 창에서 Is Browsablefalse로 설정하거나 Is UI Readonlytrue로 설정합니다.

색, 스타일 또는 위치가 모델 요소 속성에 따라 달라지도록 변경 규칙 정의

도형의 모양이 모델의 다른 부분에 종속되도록 업데이트하는 규칙을 정의할 수 있습니다. 예를 들어 모델 요소의 속성에 따라 도형의 색을 업데이트하는 변경 규칙을 모델 요소에 정의할 수 있습니다. 변경 규칙에 대한 자세한 내용은 규칙으로 모델 내부의 변경 내용 전파를 참조하세요.

실행 취소 명령이 수행되면 규칙이 호출되지 않으므로 저장소 내에서 유지 관리되는 속성을 업데이트하는 데만 규칙을 사용해야 합니다. 여기에는 도형의 크기 및 표시 여부와 같은 일부 그래픽 기능이 포함되지 않습니다. 도형의 이러한 기능을 업데이트하려면 비저장소 그래픽 기능 업데이트를 참조하세요.

다음 예에서는 이전 섹션에서 설명한 대로 도메인 속성으로 FillColor를 노출했다고 가정합니다.

[RuleOn(typeof(ExampleElement))]
  class ExampleElementPropertyRule : ChangeRule
  {
    public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e)
    {
      base.ElementPropertyChanged(e);
      ExampleElement element = e.ModelElement as ExampleElement;
      // The rule is called for every property that is updated.
      // Therefore, verify which property changed:
      if (e.DomainProperty.Id == ExampleElement.NameDomainPropertyId)
      {
        // There is usually only one shape:
        foreach (PresentationElement pel in PresentationViewsSubject.GetPresentation(element))
        {
          ExampleShape shape = pel as ExampleShape;
          // Replace this with a useful condition:
          shape.FillColor = element.Name.EndsWith("3")
                     ? System.Drawing.Color.Red : System.Drawing.Color.Green;
        }
      }
    }
  }
  // The rule must be registered:
  public partial class OnAssociatedPropertyExptDomainModel
  {
    protected override Type[] GetCustomDomainModelTypes()
    {
      List<Type> types = new List<Type>(base.GetCustomDomainModelTypes());
      types.Add(typeof(ExampleElementPropertyRule));
      // If you add more rules, list them here.
      return types.ToArray();
    }
  }

OnChildConfigured를 사용하여 도형의 속성 초기화

도형을 처음 만들 때 도형 속성을 설정하려면 다이어그램 클래스의 부분 정의에서 OnChildConfigured()를 재정의합니다. 다이어그램 클래스는 DSL 정의에서 지정되고, 생성된 코드는 Dsl\Generated Code\Diagram.cs에 있습니다. 예시:

partial class MyLanguageDiagram
{
  protected override void OnChildConfigured(ShapeElement child, bool childWasPlaced, bool createdDuringViewFixup)
  {
    base.OnChildConfigured(child, childWasPlaced, createdDuringViewFixup);
    ExampleShape shape = child as ExampleShape;
    if (shape != null)
    {
      if (!createdDuringViewFixup) return; // Ignore load from file.
      ExampleElement element = shape.ModelElement as ExampleElement;
      // Replace with a useful condition:
      shape.FillColor = element.Name.EndsWith("3")
          ? System.Drawing.Color.Red : System.Drawing.Color.Green;
    }
    // else deal with other types of shapes and connectors.
  }
}

이 메서드는 도메인 속성 및 비저장소 기능(예: 도형의 크기)에 모두 사용할 수 있습니다.

AssociateValueWith()를 사용하여 도형의 다른 기능 업데이트

그림자가 있는지 여부 또는 연결선의 화살표 스타일 같은 도형의 일부 기능에는 기능을 도메인 속성으로 노출하는 기본 제공 메서드가 없습니다. 이러한 기능의 변경은 트랜잭션 시스템의 제어 대상이 아닙니다. 따라서 사용자가 실행 취소 명령을 수행할 때 규칙이 호출되지 않기 때문에 규칙을 사용하여 기능을 업데이트하는 것은 적절하지 않습니다.

대신 OnAssociatedPropertyChanged를 사용하여 이러한 기능을 업데이트할 수 있습니다. 다음 예에서 연결선의 화살표 스타일은 연결선이 표시하는 관계의 도메인 속성 값에 의해 제어됩니다.

public partial class ArrowConnector // My connector class.
{
    /// <summary>
    /// Called whenever a registered property changes in the associated model element.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnAssociatedPropertyChanged(VisualStudio.Modeling.Diagrams.PropertyChangedEventArgs e)
    {
      base.OnAssociatedPropertyChanged(e);
      // Can be called for any property change. Therefore,
      // Verify that this is the property we're interested in:
      if ("IsDirected".Equals(e.PropertyName))
      {
        if (e.NewValue.Equals(true))
        { // Update the shape's built-in Decorator feature:
          this.DecoratorTo = LinkDecorator.DecoratorEmptyArrow;
        }
        else
        {
          this.DecoratorTo = null; // No arrowhead.
        }
      }
    }

    // OnAssociatedPropertyChanged is called only for properties
    // that have been registered using AssociateValueWith().
    // InitializeResources is a convenient place to call this.
    // This method is invoked only once per class, even though
    // it is an instance method.
    protected override void InitializeResources(StyleSet classStyleSet)
    {
      base.InitializeResources(classStyleSet);
      AssociateValueWith(this.Store, Wire.IsDirectedDomainPropertyId);
      // Add other properties here.
    }
}

AssociateValueWith()는 등록하려는 도메인 속성마다 한 번씩 호출해야 합니다. 호출된 후에는 지정된 속성의 모든 변경 내용이 속성의 모델 요소를 표시하는 모든 도형에서 OnAssociatedPropertyChanged()를 호출합니다.

인스턴스마다 AssociateValueWith()를 호출할 필요는 없습니다. InitializeResources는 인스턴스 메서드이지만 도형 클래스마다 한 번만 호출됩니다.