建議使用 Visual Studio 2017

自訂文字和影像欄位

 

如需 Visual Studio 2017 的最新文件請參閱 Visual Studio 2017 文件

當您定義圖形中的文字裝飾項目時,它會以 TextField。 有關 TextFields 和其他 ShapeFields 初始化的詳細資訊,請在 DSL 方案中檢查 Dsl\GeneratedCode\Shapes.cs。

TextField 是管理工作區 圖形,例如指派給標籤的空間中的物件。 相同類別的許多圖形之間共用一個 TextField 執行個體。 TextField 執行個體不會儲存標籤文字的每個執行個體,分別為︰ 反而GetDisplayText(ShapeElement)方法會採用圖形做為參數,並可以查詢的文字取決於目前狀態的圖案和其模型項目。

DoPaint()會呼叫方法來顯示欄位在螢幕上。 您可以覆寫預設DoPaint(),或者您可以覆寫它所呼叫的方法。 下列的簡化的版本的預設方法,可協助您了解如何覆寫預設行為︰

// Simplified version:  
public override void DoPaint(DiagramPaintEventArgs e, ShapeElement parentShape)  
{   
  string text = GetDisplayText(shape);   
  StringFormat format = GetStringFormat(parentShape);  
  Brush brush = GetTextBrush(e.View, shape);  
  using (Font font = GetFont(shape))  
  {  
    e.Graphics.DrawString(text, font, brush, format);  
  }  
}  
// StringFormat determines whether the string is centered etc.  
// To customize statically for all instances of this shape field,   
// assign to DefaultStringFormat.  
// To customize dynamically or per shape, override this:    
public virtual StringFormat GetStringFormat(ShapeElement shape)  
{ return DefaultStringFormat; }  
  
// Override to customize the displayed string:  
public virtual string GetDisplayText(ShapeElement shape)  
{ return this.GetValue(shape).ToString(); }  
  
// Brush determines the text color.  
// To change the brush for every field, change the shape’s styleset.   
// To customize to a brush in the style set, override GetTextBrushId.  
// To change the brush to non-standard color, override this.  
// Should take account of whether selected.   
public virtual Brush GetTextBrush(DiagramClientView view, ShapeElement shape)  
{ return shape.StyleSet.GetBrush(this.GetTextBrushId(view, shape)); }  
  
// Brush ID selects a brush from a StyleSet.  
// Either return a member of DiagramBrushes   
// or add your own brush to the shape or application’s styleset.  
// Override this to change dynamically or per instance.  
// To change statically, just assign to default values.   
public virtual StyleSetResourceId GetTextBrushId(DiagramClientView view, ShapeElement shape)  
{ return IsSelected(view, shape) ? (view.Focused ? DefaultSelectedTextBrushId  
: DefaultInactiveSelectedTextBrushId ) : DefaultTextBrushId ;  
}  
  
// Font determines the shape and size of the text.  
// To change the font for every field, change the shape’s styleset.   
// To customize to a font in the style set, override GetFontId.  
// To change the font to a non-standard font, override this.   
public virtual Font GetFont(ShapeElement shape)  
{ return shape.StyleSet.GetFont(GetFontId(shape)); }  
  
// Selects a font from a styleset.  
// Either return a member of DiagramFonts or   
// add your own font to the shape or application’s styleset.  
// To change statically for all instances of this field,   
// assign to DefaultFontId.  
// To change per shape or dynamically, override this.   
public virtual StyleSetResourceId GetFontId(ShapeElement parentShape)  
{ return DefaultFontId; }  
  

有幾個其他組的Get方法和Default屬性,例如DefaultMultipleLine/GetMultipleLine()。 您可以指派值給預設屬性,若要變更所有執行個體的 [圖形] 欄位的值。 若要變更一個圖形的執行個體到另一個,或是依賴的圖形或其模型項目狀態的值,請覆寫Get方法。

如果您想要變更這個圖形欄位的每個執行個體,請先找出是否設定屬性,以及在 DSL 定義中。 例如,您可以在 [屬性] 視窗中設定字型的大小和樣式。

如果沒有,則覆寫InitializeShapeFields圖形類別,以及指派到適當的值的方法Default...文字欄位的屬性。

System_CAPS_ICON_warning.jpg 警告

若要覆寫InitializeShapeFields(),您必須設定產生雙衍生圖形類別的屬性trueDSL 定義中。

在此範例中,圖形會有一個用於使用者註解的文字欄位。 我們想要使用標準註解的字型。 因為這是標準的字型樣式集,我們可以設定預設字型識別碼︰

  
 partial class ExampleShape  
{   protected override void InitializeShapeFields(IList<ShapeField> shapeFields)  
    {  
      // Fields set up according to DSL Definition:  
      base.InitializeShapeFields(shapeFields);  
      // Find and update comment field:  
      TextField commentField = ShapeElement.FindShapeField(shapeFields, "CommentDecorator") as TextField;  
      // Use the standard font for comments:  
      commentField.DefaultFontId = DiagramFonts.CommentText;  
  

若要讓不同的外觀取決於圖形或其模型項目的狀態,衍生您自己的子類別TextField並覆寫一個或多個Get...方法。 您也必須覆寫您的形狀 InitializeShapeFields 方法,並且 TextField 的執行個體取代您自己的類別的執行個體。

下列範例會使相依於圖形的模型項目的布林值的網域屬性的狀態文字欄位的字型。

若要執行此程式碼範例,建立新的 DSL 方案使用最小語言的範本。 將布林值的網域屬性加入AlternateStateExampleElement 網域類別。 將圖示裝飾項目加入至 ExampleShape 類別,並設定其影像點陣圖檔案。 按一下 轉換所有範本。 在 DSL 專案中,加入新的程式碼檔案,並插入下列程式碼。

若要測試的程式碼,按 f5 鍵,並在偵錯方案中,開啟範例圖表。 圖示的預設狀態應該會出現。 選取的圖形和 [屬性] 視窗中變更值AlternateState屬性。 應該變更的項目名稱的字型。

using Microsoft.VisualStudio.Modeling;  
using Microsoft.VisualStudio.Modeling.Diagrams;  
...  
  
  partial class ExampleShape  
  {  
    /// <summary>  
    /// Compose a list of the fields in this shape.  
    /// Called once for each shape class.  
    /// </summary>  
    protected override void InitializeShapeFields(IList<ShapeField> shapeFields)  
    {  
      // Fields set up according to DSL Definition:  
      base.InitializeShapeFields(shapeFields);  
      // Replace the text field for NameDecorator:  
      TextField oldField = ShapeElement.FindShapeField(shapeFields, "NameDecorator") as TextField;  
      shapeFields.Remove(oldField);  
      // Replace with my text field based on DSL Definition values:  
      MyTextField newField = new MyTextField(oldField);  
      shapeFields.Add(newField);  
    }  
  }  
  /// <summary>  
  /// Dynamic font depends on state of model element.  
  /// </summary>  
  public class MyTextField : TextField  
  {  
    public MyTextField(TextField prototype)  
      : base(prototype.Name)  
    {  
      DefaultText = prototype.DefaultText;  
      DefaultFocusable = prototype.DefaultFocusable;  
      DefaultAutoSize = prototype.DefaultAutoSize;  
      AnchoringBehavior.MinimumHeightInLines = prototype.AnchoringBehavior.MinimumHeightInLines;  
      AnchoringBehavior.MinimumWidthInCharacters = prototype.AnchoringBehavior.MinimumWidthInCharacters;  
      DefaultAccessibleState = prototype.DefaultAccessibleState;  
    }  
  
    public override System.Drawing.Font GetFont(ShapeElement parentShape)  
    {  
      // Access the Boolean domain property of the model element:  
      if ((parentShape.ModelElement as ExampleElement).AlternateState)  
        return new System.Drawing.Font("Callisto", 14.0f,  
               System.Drawing.FontStyle.Italic |   
               System.Drawing.FontStyle.Bold);  
      else  
        return base.GetFont(parentShape);  
    }  
  
  }  
  

先前的範例顯示如何變更文字欄位,以及在任何可用的字型。 不過,較佳的方法是將它變更為其中一組圖形或應用程式相關聯的樣式。 若要這樣做,您覆寫GetFontId或 GetTextBrushId()。

或者,請考慮藉由覆寫變更圖形的樣式集InitializeResources。 這有的字型和筆刷形狀欄位的所有變更的效果。

當您在圖形中,定義影像裝飾項目,而且當您定義了影像圖形,圖形中的顯示區域的管理方式 ImageField。 有關 ImageFields 和其他 ShapeFields 初始化的詳細資訊,請在 DSL 方案中檢查 Dsl\GeneratedCode\Shapes.cs。

ImageField 是管理工作區 圖形,例如指派給裝飾項的空間中的物件。 許多相同的圖形類別的形狀之間共用一個 ImageField 執行個體。 ImageField 執行個體不會儲存每個圖形的個別映像︰ 反而GetDisplayImage(ShapeElement)方法會採用圖形做為參數,並可以查閱相依於目前的圖形和其模型項目狀態的映像。

如果您想特殊的行為,例如變數的映像,您可以建立您自己的類別衍生自 ImageField。

若要建立的 ImageField 子類別

  1. 設定產生雙衍生DSL 定義中的父圖形類別的屬性。

  2. 覆寫InitializeShapeFields圖形類別的方法。

    • 在 DSL 專案中,建立新的程式碼檔案並撰寫 shape 類別的部分類別定義。 覆寫的方法定義。
  3. 檢查使用的程式碼InitializeShapeFieldsDSL\GeneratedCode\Shapes.cs 中。

    您覆寫方法會呼叫基底方法,然後建立您自己的映像欄位類別的執行個體。 使用此選項可取代的一般映像欄位shapeFields清單。

此範例會將相依於圖形的模型項目的狀態變更的圖示。

System_CAPS_ICON_warning.jpg 警告

此範例示範如何進行動態影像裝飾項目。 但如果您只想要根據的模型變數狀態的一或兩個映像之間切換,很容易建立數個映像裝飾項目,在圖形上,相同的位置找到這些服務,然後設定 可見性篩選,以特定模型變數的值而定。 若要設定此篩選器,選取圖案對應 DSL 定義中,開啟 [DSL 詳細資料] 視窗中,然後按一下 [裝飾項目] 索引標籤。

若要執行此程式碼範例,建立新的 DSL 方案使用最小語言的範本。 將布林值的網域屬性加入AlternateStateExampleElement 網域類別。 將圖示裝飾項目加入至 ExampleShape 類別,並設定其影像點陣圖檔案。 按一下 轉換所有範本。 在 DSL 專案中,加入新的程式碼檔案,並插入下列程式碼。

若要測試的程式碼,按 f5 鍵,並在偵錯方案中,開啟範例圖表。 圖示的預設狀態應該會出現。 選取的圖形和 [屬性] 視窗中變更值AlternateState屬性。 應該再出現旋轉 90 度,該圖形上透過圖示。

using Microsoft.VisualStudio.Modeling;  
using Microsoft.VisualStudio.Modeling.Diagrams;  
...  
partial class ExampleShape  
{  
    /// <summary>  
    /// Compose a list of the fields in this shape.  
    /// Called once for each shape class.  
    /// </summary>  
    /// <param name="shapeFields"></param>  
    protected override void InitializeShapeFields(IList<ShapeField> shapeFields)  
    {  
      // Fields set up according to DSL Definition:  
      base.InitializeShapeFields(shapeFields);  
  
      // Replace the image field:  
      ShapeField oldField = ShapeElement.FindShapeField(shapeFields, "IconDecorator");  
      shapeFields.Remove(oldField);  
      // Must keep the same name:  
      MyImageField newField = new MyImageField(oldField.Name);  
      shapeFields.Add(newField);  
      newField.DefaultImage = (oldField as ImageField).DefaultImage.Clone() as System.Drawing.Image;  
    }  
  }  
  
  public class MyImageField : ImageField  
  {  
    public MyImageField(string tag) : base(tag) { }  
  
    /// <summary>  
    /// Get the image for this field in the given shape.  
    /// </summary>  
    public override System.Drawing.Image GetDisplayImage(ShapeElement parentShape)  
    {  
      ExampleElement element = parentShape.ModelElement as ExampleElement;  
      if (element.AlternateState == true)  
        return AlternateImage;  
      else  
        return base.GetDisplayImage(parentShape);  
    }  
  
    private System.Drawing.Image alternateImage;  
    public System.Drawing.Image AlternateImage  
    {  
      get  
      {  
        if (alternateImage == null)  
        {  
          // Alternate image is a copy of the default, rotated by 90 degrees:  
          alternateImage = this.DefaultImage.Clone() as System.Drawing.Image;  
          alternateImage.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipNone);  
        }  
        return alternateImage;  
      }  
    }  
  }  
}  
  

定義圖案和連接器
在圖表上設定的背景影像
巡覽和更新程式碼中的模型
撰寫程式碼來自訂定義域專屬語言

顯示: