更新圖案和接點來反映模型

在中以定義域專屬語言Visual Studio,您可以將反映基礎的模型的狀態圖形的外觀。

本主題中的程式碼範例加入至.cs檔案中您Dsl專案。您必須在每個檔案中的這些陳述式:

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

設定圖案對應的屬性,以控制裝飾的可見性

您可以控制裝飾的可見性,而不需要撰寫程式碼,藉由設定 DSL 定義中的圖形與網域類別之間的對應。如需詳細資訊,請參閱下列主題:

公開 (expose) 的色彩與圖案的樣式屬性

在 DSL 定義中,以滑鼠右鍵按一下圖形類別,並指向加入公開,然後按一下其中一個項目如 填滿色彩

圖形現在都具有網域屬性,您可以在程式碼,或以使用者設定。例如,若要將它設定在 「 指令 」 或 「 規則的程式碼中,您可以撰寫:

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

如果您要讓屬性變數只能在程式的控制項,並不是由使用者,請選取新的網域屬性例如填滿色彩 DSL 定義圖表中。然後,在 [屬性] 視窗中,設定是可瀏覽到false或設定是 UI Readonly 到true。

定義變更的規則,才能使色彩、 樣式或位置取決於模型元素屬性

您可以定義規則以更新相依於該模型的其他部份圖形的外觀。例如,您可定義變更規則,以更新其模型項目的屬性而定的形狀的色彩模型項目上。如需有關變更規則的詳細資訊,請參閱規則傳播模型內的變更

您應該使用規則,才能更新會儲存在存放區內,保留的屬性,因為規則不會叫用時執行 [復原] 指令。這不包括一些圖形化的功能,例如大小和形狀的可視性。若要更新這些圖形的功能,請參閱更新存放區的非圖形化功能。

下列範例會假設您有公開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 執行個體方法,它就會叫用一次,每個圖形類別。