Compartir a través de


Actualizar formas y conectores para reflejar el modelo

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

Los ejemplos de código de este tema se deben agregar a un archivo .cs del proyecto Dsl. Necesita estas directivas en cada archivo:

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

Establecimiento de las propiedades de la asignación de forma para controlar la visibilidad de un decorador

Puede controlar la visibilidad de un decorador sin escribir código de programa mediante la configuración de la asignación entre la forma y la clase de dominio en la definición de DSL. Para obtener más información, consulte Cómo: Definir lenguajes específicos de dominio.

Exposición del color y el estilo de una forma como propiedades

En la definición de DSL, haga clic con el botón derecho en la clase de forma, seleccione Agregar expuestay, después, en uno de los elementos, por ejemplo, Color de relleno.

La forma ahora tiene una propiedad de dominio que puede establecer en código de programa o como usuario. Por ejemplo, para establecerlo en el código de programa de un comando o regla, puede escribir lo siguiente:

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

Si desea que la variable de propiedad solo esté bajo control de programa y no del usuario, seleccione la propiedad de dominio nueva, como Color de relleno, en el diagrama de definición de DSL. Después, en la ventana Propiedades, establezca Is Browsable en false o establezca Is UI Readonly (Es de solo lectura de UI) en true.

Definición de Reglas de cambio para que el color, el estilo o la ubicación dependan de las propiedades del elemento del modelo

Puede definir reglas que actualicen la apariencia de la forma que dependan de otras partes del modelo. Por ejemplo, podría definir una Regla de cambio en un elemento de modelo que actualice el color de su forma según las propiedades del elemento de modelo. Para más información sobre las reglas de cambio, consulte Las reglas propagan los cambios dentro del modelo.

Solo debe usar reglas para actualizar las propiedades que se mantienen en Store, ya que las reglas no se invocan cuando se realiza el comando Deshacer. Esta acción no incluye algunas características gráficas, como el tamaño y la visibilidad de una forma. Para actualizar esas características en una forma, consulte Uso de AssociateValueWith() para actualizar otras características de una forma.

En el ejemplo siguiente se supone que se ha expuesto FillColor como una 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 de OnChildConfigured para inicializar las propiedades de una forma

Para establecer las propiedades de una forma cuando se crea por primera vez, la invalidación OnChildConfigured() en una definición parcial de la clase de diagrama. La clase de diagrama se especifica en la definición de DSL y el código generado se encuentra 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 usar tanto para las propiedades de dominio como para las características que no son de almacén, como el tamaño de la forma.

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

Para algunas características de una forma, como si tiene una sombra o el estilo de flecha de un conector, no hay ningún método integrado para exponer la característica como una propiedad de dominio. Los cambios en estas características no los controla el sistema de transacciones. Por lo tanto, no es adecuado actualizarlos mediante reglas, ya que las reglas no se invocan cuando el usuario usa el comando Deshacer.

En su lugar, estas características se pueden actualizar mediante 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 muestra el conector:

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 una vez por cada propiedad de dominio que quiera registrar. Tras la llamada, los cambios realizados en la propiedad especificada llamarán a OnAssociatedPropertyChanged() en cualquier forma que presente el elemento de modelo de la propiedad.

No hace falta llamar a AssociateValueWith() para cada instancia. Aunque InitializeResources es un método de instancia, se invoca solo una vez para cada clase de forma.