共用方式為


建立 Windows Forms 架構的特定領域語言

您可以使用 Windows Forms 來顯示特定領域語言 (DSL) 模型的狀態,而不是使用 DSL 圖表。 本主題會逐步引導您使用 Visual Studio Visualization and Modeling SDK 將 Windows Form 繫結至 DSL。

下圖顯示 DSL 執行個體的 Windows Form UI 和模型總管:

DSL instance in Visual Studio

建立 Windows Forms DSL

最小 WinForm 設計工具 DSL 範本會建立最小 DSL,您可以修改以符合自己的需求。

  1. 最小 WinForm 設計工具範本建立 DSL。

    在本逐步解說中,假設有下列名稱:

    • 解決方案和 DSL 名稱:FarmApp
    • 命名空間:Company.FarmApp
  2. 實驗範本提供的初始範例:

    1. 轉換所有範本。

    2. 建置並執行範例 (Ctrl+F5)。

    3. 在 Visual Studio 的實驗執行個體中,開啟偵錯專案中的 Sample 檔案。

      請注意,該檔案會顯示在 Windows Forms 控制項中。

      您也可以查看 [總管] 中顯示的模型元素。

      在表單或檔案總管中新增一些元素,並注意其出現在另一個顯示中。

    在 Visual Studio 的主要執行個體中,請注意有關 DSL 解決方案的下列幾點:

  • DslDefinition.dsl 不包含任何圖表元素。 這是因為您不會使用 DSL 圖表來檢視此 DSL 的執行個體模型。 相反地,您會將 Windows Form 繫結至模型,而表單上的元素會顯示模型。

  • 除了 DslDslPackage 專案之外,解決方案還包含名為 UI.UI 專案的第三個專案,其中包含 Windows Forms 控制項的定義。 DslPackage 相依於 UI,而 UI 相依於 Dsl

  • DslPackage 專案中,UI\DocView.cs 包含程式碼,顯示 UI 專案中定義的 Windows Forms 控制項。

  • UI 專案包含繫結至 DSL 之表單控制項的工作範例。 不過,當您變更 DSL 定義時,將無法運作。 UI 專案包含:

    • 名為 ModelViewControl 的 Windows Form 類別。

    • 名為 DataBinding.cs 的檔案,其中包含 ModelViewControl 的額外部分定義。 若要查看其內容,請在 [方案總管] 中,開啟檔案的捷徑功能表,然後選擇 [檢視程式碼]

關於 UI 專案

當您更新 DSL 定義檔來定義自己的 DSL 時,您必須更新 UI 專案中的控制項以顯示您的 DSL。 不同於 DslDslPackage 專案,範例 UI 專案不會從 DslDefinitionl.dsl 產生。 如果您想要的話,您可以新增 .tt 檔案來產生程式碼,但是本逐步解說中並未涵蓋。

更新 DSL 定義

下圖是本逐步解說中使用的 DSL 定義。

DSL definition

  1. 在 DSL 設計工具中開啟 DslDefinition.dsl。

  2. 刪除 [ExampleElement]

  3. ExampleModel 領域類別重新命名為 Farm

    為其提供類型為 Int32 時名為 Size、類型為布林值時名為 IsOrganic 的額外領域屬性。

    注意

    如果您刪除根領域類別,然後建立新的根領域類別,則必須重設編輯器根類別屬性。 在 DSL 總管中,選取 [編輯器]。 然後在 [屬性] 視窗中,將 [根類別] 設定為 Farm

  4. 使用具名領域類別工具來建立下列領域類別:

    • Field - 為此項目提供名為 Size 的額外領域屬性。

    • Animal - 在 [屬性] 視窗中,將 [繼承修飾元] 設定為 [抽象]

    注意

    具名領域類別工具和本節中所述的其他工具可以在 [工具箱] 工具視窗中找到。 您可以使用 [檢視]> [工具箱] 來開啟或隱藏此視窗。

  5. 使用領域類別工具來建立下列類別:

    • Sheep

    • Goat

  6. 使用繼承工具讓 GoatSheepAnimal 繼承。

  7. 使用內嵌工具在 Farm 底下內嵌 FieldAnimal

  8. 您可能想要清理圖表。 若要減少重複元素的數目,請使用分葉元素捷徑功能表上的 [將樹狀子目錄放到這裡] 命令。

  9. [方案總管] 的工具列中的 [轉換所有範本]

  10. 建置 Dsl 專案。

    注意

    在這個階段,其他專案將不會建置,不會發生錯誤。 不過,我們想要建置 Dsl 專案,使其組件可供資料來源精靈使用。

更新 UI 專案

現在您可以建立新的使用者控制項,以顯示儲存在 DSL 模型中的資訊。 將使用者控制項連線到模型最簡單的方式是透過資料繫結。 名為 ModelingBindingSource 的資料繫結配接器類型特別設計為將 DSL 連線到非 VMSDK 介面。

將您的 DSL 模型定義為資料來源

  1. 選擇 [資料] 功能表上的 [顯示資料來源]

    [資料來源] 視窗隨即開啟。

    選擇 [加入新資料來源]。 [資料來源組態精靈] 隨即開啟。

  2. 選擇 [物件]、[下一步]

    展開 [Dsl]、[Company.FarmApp],然後選取 [Farm],這是您模型的根類別。 選擇 [完成]

    在 [方案總管] 中,UI 專案現在包含 Properties\DataSources\Farm.datasource

    模型類別的屬性和關聯性會出現在 [資料來源] 視窗中。

    Data sources window

將模型連線到表單

  1. UI 專案中,刪除所有現有的 .cs 檔案。

  2. 將名為 FarmControl 的新使用者控制項檔案新增至 UI 專案。

  3. 在 [資料來源] 視窗的 [伺服器陣列] 下拉式功能表上,選擇 [詳細資料]

    針對其他屬性保留預設設定。

  4. 在設計檢視中開啟 FarmControl.cs。

    將 [伺服器陣列] 從 [資料來源] 視窗拖曳至 FarmControl。

    一組控制項隨即出現,每個屬性各一個控制項。 關聯性屬性不會產生控制項。

  5. 刪除 farmBindingNavigator。 這也會在 FarmControl 設計工具中自動產生,但是不適用於此應用程式。

  6. 使用工具箱,建立兩個 DataGridView 的執行個體,並將其命名為 AnimalGridViewFieldGridView

    注意

    替代的步驟是將「動物」和「欄位」項目從 [資料來源] 視窗拖曳至控制項。 此動作會自動在方格檢視與資料來源之間建立資料格線和繫結。 不過,此繫結不適用於 DSL。 因此,最好手動建立資料格線和繫結。

  7. 如果 [工具箱] 不包含 ModelingBindingSource 工具,請加以新增。 在 [資料] 索引標籤的捷徑功能表上,選擇 [選擇項目]。 在 [選擇工具箱項目] 對話方塊中,從 [.NET Framework] 索引標籤中選取 [ModelingBindingSource]

  8. 使用工具箱,建立兩個 ModelingBindingSource 的執行個體,並將其命名為 AnimalBindingFieldBinding

  9. 將每個 ModelingBindingSourceDataSource 屬性設定為 farmBindingSource

    DataMember 屬性設定為 AnimalsFields

  10. AnimalGridViewDataSource 屬性設定為 AnimalBinding,以及將 FieldGridView 的該屬性設定為 FieldBinding

  11. 調整伺服器陣列控制項的版面配置以符合您的品味。

    ModelingBindingSource 是一個介面卡,可執行數個 DSL 特定的函式:

  • 它會將更新包裝在 VMSDK 存放區交易中。

    例如,當使用者從資料檢視方格刪除資料列時,一般繫結會導致交易例外狀況。

  • 它可確保當使用者選取資料列時,[屬性] 視窗會顯示對應模型元素的屬性,而不是資料格線資料列。

    Schema of the DSL binding

    資料來源與檢視之間的連結結構描述。

完成 DSL 的繫結

  1. UI 專案的個別程式碼檔案中,新增下列程式碼:

    using System.ComponentModel;
    using Microsoft.VisualStudio.Modeling;
    using Microsoft.VisualStudio.Modeling.Design;
    
    namespace Company.FarmApp
    {
      partial class FarmControl
      {
        public IContainer Components { get { return components; } }
    
        /// <summary>Binds the WinForms data source to the DSL model.
        /// </summary>
        /// <param name="nodelRoot">The root element of the model.</param>
        public void DataBind(ModelElement modelRoot)
        {
          WinFormsDataBindingHelper.PreInitializeDataSources(this);
          this.farmBindingSource.DataSource = modelRoot;
          WinFormsDataBindingHelper.InitializeDataSources(this);
        }
      }
    }
    
  2. DslPackage 專案中,編輯 DslPackage\DocView.tt 以更新下列變數定義:

    string viewControlTypeName = "FarmControl";
    

測試 DSL

DSL 解決方案現在可以建置並執行,不過您稍後可能會想要新增進一步的改善。

  1. 建置並執行方案。

  2. 在 Visual Studio 的實驗性執行個體中,開啟範例檔案。

  3. FarmApp Explorer 中,開啟 [伺服器陣列] 根節點上的捷徑功能表,然後選擇 [新增山羊]

    Goat1 會出現在 [動物] 檢視中。

    警告

    您必須使用 [伺服器陣列] 節點上的捷徑功能表,而不是 [動物] 節點。

  4. 選取 [伺服器陣列] 根節點並檢視其屬性。

    在表單檢視中,變更伺服器陣列的 [Name] 或 [Size]

    當您離開表單中的每個欄位時,對應的屬性就會在 [屬性] 視窗中變更。

增強 DSL

立即更新屬性

  1. 在 FarmControl.cs 的設計檢視中,選取簡單的欄位,例如 [Name]、[Size] 或 [IsOrganic]。

  2. 在 [屬性] 視窗中,展開 [DataBindings] 節點,並且開啟 [(進階)]

    在 [格式化與進階繫結] 對話方塊的 [資料來源更新模式] 底下,選擇 [OnPropertyChanged]

  3. 建置並執行方案。

    確認當您變更欄位的內容時,伺服器陣列模型的對應屬性會立即變更。

提供新增按鈕

  1. 在 FarmControl.cs 的設計檢視中,使用工具箱在表單上建立按鈕。

    編輯按鈕的名稱和文字,例如 New Sheep

  2. 開啟按鈕後面的程式碼 (例如按兩下按鈕)。

    如下所示進行編輯:

    private void NewSheepButton_Click(object sender, EventArgs e)
    {
      using (Transaction t = farm.Store.TransactionManager.BeginTransaction("Add sheep"))
      {
        elementOperations.MergeElementGroup(farm,
          new ElementGroup(new Sheep(farm.Partition)));
        t.Commit();
      }
    }
    
    // The following code is shared with other add buttons:
    private ElementOperations operationsCache = null;
    private ElementOperations elementOperations
    {
      get
      {
        if (operationsCache == null)
        {
          operationsCache = new ElementOperations(farm.Store, farm.Partition);
        }
        return operationsCache;
      }
    }
    private Farm farm
    {
      get { return this.farmBindingSource.DataSource as Farm; }
    }
    

    您也需要插入下列指示詞:

    
    using Microsoft.VisualStudio.Modeling;
    
  3. 為「山羊」和「欄位」新增類似的按鈕。

  4. 建置並執行方案。

  5. 確認新按鈕新增為項目。 新的項目應該同時出現在 FarmApp Explorer 和適當的資料格線檢視中。

    您應該能夠在資料格線檢視中編輯元素的名稱。 您也可以從該處刪除。

    Sample data grid view

關於要新增元素的程式碼

對於新元素按鈕,下列替代程式碼會稍微簡單一點。

private void NewSheepButton_Click(object sender, EventArgs e)
{
  using (Transaction t = farm.Store.TransactionManager.BeginTransaction("Add sheep"))
  {
    farm.Animals.Add(new Sheep(farm.Partition)); ;
    t.Commit();
  }
}

不過,此程式碼不會設定新項目的預設名稱。 不會執行您可能已在 DSL 元素合併指示詞中定義的任何自訂合併,也不會執行任何可能已定義的自訂合併程式碼。

因此,建議您使用 ElementOperations 來建立新的元素。 如需詳細資訊,請參閱自訂元素建立和移動