Condividi tramite


Aggiornare forme e connettori per riflettere il modello

In un linguaggio specifico del dominio in Visual Studio è possibile fare in modo che l'aspetto di una forma rifletta lo stato del modello sottostante.

Gli esempi di codice in questo argomento devono essere aggiunti a un .cs file nel Dsl progetto. Queste direttive sono necessarie in ogni file:

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

Impostare le proprietà della mappa delle forme per controllare la visibilità di un elemento Decorator

È possibile controllare la visibilità di un elemento Decorator senza scrivere codice programma, configurando il mapping tra la forma e la classe di dominio nella definizione DSL. Per altre informazioni, vedere How to Define a Domain-Specific Language.For more information, see How to Define a Domain-Specific Language.

Esporre il colore e lo stile di una forma come proprietà

Nella definizione DSL fare clic con il pulsante destro del mouse sulla classe forma, scegliere Aggiungi esposto e quindi fare clic su uno degli elementi, ad esempio Fill Color.

La forma ha ora una proprietà di dominio che è possibile impostare nel codice del programma o come utente. Ad esempio, per impostarlo nel codice del programma di un comando o di una regola, è possibile scrivere:

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

Se si desidera impostare la variabile di proprietà solo sotto il controllo del programma e non dall'utente, selezionare la nuova proprietà di dominio, ad esempio Fill Color (Colore riempimento) nel diagramma di definizione DSL. Quindi, nella Finestra Proprietà impostare Is Browsable su false o impostare Is UI Readonly su true.

Definire le regole di modifica per rendere il colore, lo stile o la posizione dipendono dalle proprietà degli elementi del modello

È possibile definire regole che aggiornano l'aspetto della forma dipendente da altre parti del modello. Ad esempio, è possibile definire una regola di modifica in un elemento del modello che aggiorna il colore della forma in base alle proprietà dell'elemento del modello. Per altre informazioni sulle regole di modifica, vedere Propagazione delle modifiche all'interno del modello.

È consigliabile usare le regole solo per aggiornare le proprietà mantenute all'interno dello Store, perché le regole non vengono richiamate quando viene eseguito il comando Annulla. Ciò non include alcune caratteristiche grafiche, ad esempio le dimensioni e la visibilità di una forma. Per aggiornare queste funzionalità di una forma, vedere Aggiornamento delle funzionalità grafiche non archiviate.

Nell'esempio seguente si presuppone che sia stata esposta FillColor come proprietà di dominio come descritto nella sezione precedente.

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

Utilizzare OnChildConfigured per inizializzare le proprietà di una forma

Per impostare le proprietà di una forma quando viene creata per la prima volta, eseguire l'override OnChildConfigured() in una definizione parziale della classe diagramma. La classe diagramma viene specificata nella definizione DSL e il codice generato si trova in Dsl\Generated Code\Diagram.cs. Ad esempio:

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

Questo metodo può essere usato sia per le proprietà di dominio che per le funzionalità non archiviate, ad esempio le dimensioni della forma.

Utilizzare AssociateValueWith() per aggiornare altre funzionalità di una forma

Per alcune caratteristiche di una forma, ad esempio se ha un'ombreggiatura o lo stile freccia di un connettore, non esiste alcun metodo predefinito per esporre la funzionalità come proprietà di dominio. Le modifiche apportate a tali funzionalità non sono sotto il controllo del sistema di transazioni. Pertanto, non è appropriato aggiornarli usando regole, perché le regole non vengono richiamate quando l'utente esegue il comando Annulla.

È invece possibile aggiornare tali funzionalità usando OnAssociatedPropertyChanged. Nell'esempio seguente lo stile freccia di un connettore è controllato da un valore di una proprietà di dominio nella relazione visualizzata dal connettore:

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() deve essere chiamato una volta per ogni proprietà di dominio che si desidera registrare. Dopo la chiamata, tutte le modifiche apportate alla proprietà specificata verranno chiamate OnAssociatedPropertyChanged() in tutte le forme che presentano l'elemento del modello della proprietà.

Non è necessario chiamare AssociateValueWith() per ogni istanza. Sebbene InitializeResources sia un metodo di istanza, viene richiamato una sola volta per ogni classe di forma.