Aktualizowanie kształtów i łączników, aby odzwierciedlały model

W języku specyficznym dla domeny w programie Visual Studio wygląd kształtu może odzwierciedlać stan modelu bazowego.

Przykłady kodu w tym temacie powinny zostać dodane do .cs pliku w Dsl projekcie. Te dyrektywy są potrzebne w każdym pliku:

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

Ustawianie właściwości mapy kształtów w celu kontrolowania widoczności dekoratora

Widoczność dekoratora można kontrolować bez pisania kodu programu, konfigurując mapowanie między kształtem a klasą domeny w definicji DSL. Aby uzyskać więcej informacji, zobacz How to Define a Domain-Specific Language (Jak zdefiniować język specyficzny dla domeny).

Uwidacznia kolor i styl kształtu jako właściwości

W definicji DSL kliknij prawym przyciskiem myszy klasę kształtu, wskaż polecenie Dodaj uwidocznione, a następnie kliknij jeden z elementów, takich jak Kolor wypełnienia.

Kształt ma teraz właściwość domeny, którą można ustawić w kodzie programu lub jako użytkownik. Aby na przykład ustawić go w kodzie programu polecenia lub reguły, możesz napisać:

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

Jeśli chcesz ustawić zmienną właściwości tylko w obszarze kontroli programu, a nie przez użytkownika, wybierz nową właściwość domeny, taką jak Kolor wypełnienia na diagramie definicji DSL. Następnie w okno Właściwości ustaw wartość Is Browsable na false lub ustaw wartość Is UI Readonly na truewartość .

Definiowanie reguł zmiany w celu zmiany koloru, stylu lub lokalizacji zależy od właściwości elementu modelu

Można zdefiniować reguły aktualizujące wygląd kształtu zależne od innych części modelu. Można na przykład zdefiniować regułę zmiany elementu modelu, który aktualizuje kolor kształtu w zależności od właściwości elementu modelu. Aby uzyskać więcej informacji na temat reguł zmian, zobacz Propagacja zmian w regułach w modelu.

Reguły należy używać tylko do aktualizowania właściwości, które są przechowywane w Magazynie, ponieważ reguły nie są wywoływane po wykonaniu polecenia Cofnij. Nie obejmuje to niektórych funkcji graficznych, takich jak rozmiar i widoczność kształtu. Aby zaktualizować te funkcje kształtu, zobacz Aktualizowanie funkcji graficznych niezwiązanych z magazynem.

W poniższym przykładzie przyjęto założenie, że uwidoczniono FillColor jako właściwość domeny zgodnie z opisem w poprzedniej sekcji.

[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();
    }
  }

Użyj polecenia OnChildConfigured, aby zainicjować właściwości kształtu

Aby ustawić właściwości kształtu po jego utworzeniu, przesłonięcia OnChildConfigured() w częściowej definicji klasy diagramu. Klasa diagramu jest określona w definicji DSL, a wygenerowany kod znajduje się w pliku Dsl\Generated Code\Diagram.cs. Na przykład:

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

Ta metoda może służyć zarówno dla właściwości domeny, jak i funkcji innych niż store, takich jak rozmiar kształtu.

Używanie metody AssociateValueWith() do aktualizowania innych funkcji kształtu

W przypadku niektórych funkcji kształtu, takich jak cień lub styl strzałki łącznika, nie ma wbudowanej metody uwidaczniania funkcji jako właściwości domeny. Zmiany w takich funkcjach nie są pod kontrolą systemu transakcji. W związku z tym nie jest odpowiednie zaktualizowanie ich przy użyciu reguł, ponieważ reguły nie są wywoływane, gdy użytkownik wykonuje polecenie Cofnij.

Zamiast tego można zaktualizować takie funkcje przy użyciu polecenia OnAssociatedPropertyChanged. W poniższym przykładzie styl strzałki łącznika jest kontrolowany przez wartość właściwości domeny w relacji wyświetlanej przez łącznik:

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() powinien być wywoływany jeden raz dla każdej właściwości domeny, którą chcesz zarejestrować. Po jej wywołaniu wszelkie zmiany w określonej właściwości będą wywoływane OnAssociatedPropertyChanged() w dowolnych kształtach, które przedstawiają element modelu właściwości.

Nie jest konieczne wywołanie AssociateValueWith() każdego wystąpienia. Mimo że InitializeResources jest metodą wystąpienia, jest wywoływana tylko raz dla każdej klasy kształtu.