Actualizar formas y conectores para reflejar el modelo

En un lenguaje específico de Visual Studio, puede hacer que la apariencia de una forma refleja el estado del modelo subyacente.

Los ejemplos de código de este tema se deben agregar a un archivo de .cs en el proyecto de Dsl .Necesitará estas instrucciones en cada archivo:

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

La forma determinada asigna propiedades para controlar la visibilidad de un elemento decorator

Puede controlar la visibilidad de un elemento decorator sin escribir código de programa, si configura la asignación entre la forma y la clase de dominio en la definición del ADSL.Para obtener más información, vea los temas siguientes:

Exponga el color y estilo de una forma como propiedades

En la definición de DSL, haga clic con el botón secundario en la clase shape, elija agregue expuesto, y haga clic en uno de los elementos como Color de relleno.

La forma ahora tiene una propiedad de dominio que se puede establecer en código de programa o como usuario.Por ejemplo, para especificar en el código de programa de un comando o una regla, podría escribir:

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

Si desea crear la variable de propiedad sólo en el control del programa, y no por el usuario, seleccione la nueva propiedad de dominio como Color de relleno en el diagrama de la definición del ADSL.A continuación, en la ventana Propiedades, establezca Es modificable a false o Es readonly de la interfaz de usuario determinado a true.

Definir las reglas de cambio para crear un color, estilo o ubicación depende de las propiedades de elementos del modelo

Puede definir reglas que actualizan el aspecto el dependiente de forma en otras partes del modelo.Por ejemplo, puede definir una regla de cambio de un elemento de modelo que actualiza el color del dependiente de forma en las propiedades del elemento de modelo.Para obtener más información sobre las reglas de cambio, vea Las reglas propagan los cambios dentro del modelo.

Debe utilizar reglas para actualizar sólo las propiedades que se mantienen en el almacén, porque las reglas no se invocan cuando realizan el comando deshacer.Esto no incluye algunas características gráficas como el tamaño y la visibilidad de una forma.para actualizar esas características de una forma, vea Actualizar características gráficas de No-Almacén.

El ejemplo siguiente supone que ha expuesto FillColor como propiedad de dominio como se describe en la sección anterior.

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

Uso OnChildConfigured de inicializar las propiedades de una forma

Para establecer las propiedades de una forma cuando se crea por primera vez, el reemplazo OnChildConfigured() en una definición de clase parcial del diagrama.La clase del diagrama se especifica en la definición de DSL, y el código generado está en Dsl\Generated Code\Diagram.cs.Por ejemplo:

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

Este método se puede utilizar para las propiedades de dominio y las características de no-almacén, como el tamaño de la forma.

utilice AssociateValueWith() para actualizar otras características de una forma

Para algunas características de una forma, por ejemplo si tiene una sombra, o el estilo de flecha de un conector, no hay ningún método integrado de exponer la característica como propiedad de dominio.Los cambios a estas características no están bajo el control de transacción.Por consiguiente, no es adecuado actualizarlas mediante reglas, porque las reglas no se invocan cuando el usuario realiza el comando deshacer.

En su lugar, puede actualizar estas características utilizando OnAssociatedPropertyChanged.En el ejemplo siguiente, el estilo de flecha de un conector se controla mediante un valor de una propiedad de dominio en la relación que el conector muestra:

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() se debe llamar a una vez para cada propiedad de dominio que desea registrar.Después de llamar a, cualquier cambio a la propiedad especificada a OnAssociatedPropertyChanged() en las formas que muestren el elemento modelo de la propiedad.

No es necesario llamar a AssociateValueWith() para cada instancia.Aunque InitializeResources es un método de instancia, sólo se llama una vez para cada clase shape.