共用方式為


自訂項目的建立和移動

您可以允許的項目,將它們拖曳至另一個,從工具箱] 中或在 [貼上或移動作業。 您可以讓移動的項目連結至目標項目中,使用您指定的關聯。

項目合併指示詞 (EMD) 會指定一個模型項目時,會發生什麼事合併到其他模型元素。 發生這種情況時:

  • 使用者將從工具箱拖曳至圖表] 或 [圖形] 拖曳。

  • 使用者建立的項目,藉由在 [檔案總管] 或 [區間] 圖形中的 [新增] 選單。

  • 使用者會將項目從一個區隔線移到另一個。

  • 使用者會貼上項目。

  • 您的程式碼會呼叫項目合併的指示詞。

雖然建立作業,可能會看不同的複製作業,其實際成果一樣。 當加入項目時,例如從工具箱] 中,它的原型會複寫。 原型會合併到模型中,以相同的方式,為模型的另一個組件被複製的項目。

EMD 的責任是決定如何物件群組應該合併至模型中的特定位置。 特別是,它會決定何種關聯性應該連結至模型的合併的群組例項化。 您也可以自訂該設定的屬性,並建立其他物件。

角色的元素合併指示詞

DSL-EMD_Merge

當您定義內嵌的關聯性時,會自動產生的 EMD。 當使用者新增至父代的新子執行個體,此預設值為 EMD 就會建立關聯性的執行個體。 您可以藉由加入自訂程式碼,例如修改這些預設 EMDs 中。

您也可以新增您自己 EMDs 在 DSL 定義中,讓使用者拖曳或貼上的 [合併與接收的類別的不同組合。

定義的項目合併的指示詞

您可以將項目合併的指示詞加入網域類別、 網域關係、 圖形、 連接線和圖表。 您可以新增或接收的網域類別在 DSL 總管] 中找到它們。 接收的類別是網域類別,而且已經在模型中,拖曳到新的或複製的項目合併的項目。

DSL-EMD_Details

編製索引的類別是網域類別,將會併入接收類別成員的項目。 子索引類別的執行個體也會合併依此 EMD,除非您設定適用於子類別設為 False。

有兩種合併指示詞:

  • A 合併處理程序指示詞會指定所用的新項目應該連結到樹狀結構的關聯性。

  • A 向前合併指示詞將新的項目重新導向至另一個接收的項目,通常是父代。

您可以新增自訂的程式碼,以合併指示詞:

  • 設定使用自訂接受來加入您自己的程式碼,以判斷是否應該將索引項目的特定執行個體合併到目標項目。 當使用者拖曳時從工具箱] 中,「 無效 」 的指標就會顯示是否您的程式碼不允許合併。

    例如,您可能會接收的項目處於特定狀態時,才允許合併。

  • 設定會使用自訂合併將提供自己的程式碼,以定義執行合併列印時對模型所做的變更。

    例如,您可以使用它在模型中的新位置中的資料,合併的項目中設定屬性。

注意事項注意事項

如果您撰寫自訂的合併列印的程式碼時,它會影響執行是藉由使用這個 EMD 的唯一合併。如果有其他 EMDs 的合併相同類型的物件,或是如果沒有其他自訂的程式碼,建立這些物件,而不要使用 EMD,然後他們將不會受到您的自訂合併程式碼。

如果您想要確保新的項目或新的關聯性永遠處理由自訂程式碼,請考慮定義AddRule上內嵌的關聯性和DeleteRule項目的網域類別上。如需詳細資訊,請參閱規則傳播模型內的變更

範例: 定義不使用自訂程式碼的情況下,為 EMD

下列範例會讓使用者可以同時建立項目和一條連接線,從工具箱] 拖曳到現有的圖形] 拖曳。 此範例會將 EMD 加入 DSL 定義。 之前這個修改之後,使用者可以將工具拖曳到圖表中,但不是到現有的圖形。

使用者也會複製到其他元素的項目。

若要讓使用者在此同時,建立項目和一條連接線

  1. 使用 [建立新的 DSL 降到最低的語言方案範本。

    當您執行這個 DSL 時,它可讓您建立的圖形] 及 [圖形之間的連接線。 您無法拖曳新 ExampleElement 圖形從工具箱拖曳至現有的圖案。

  2. 若要讓合併到元件的使用者ExampleElement圖形,建立新的 EMD 在ExampleElement網域類別:

    1. DSL 總管,展開 網域類別。 以滑鼠右鍵按一下ExampleElement ,然後按一下 [ 加入新項目合併指引

    2. 請確定 DSL 詳細資料視窗是開啟的如此您可以看到新的 EMD 的詳細資料。 (功能表: 檢視上層DSL 詳細資料。)

  3. 設定索引類別在 DSL 細節] 視窗中,以定義何種類別的項目可以合併到ExampleElement物件。

    這個範例中,選取 [ ExampleElements,如此使用者可以將新的項目拖曳至現有的項目。

    請注意編製索引的類別,將會變成 EMD,DSL 總管] 中的名稱。

  4. 藉由建立連結的處理程序合併,新增兩個路徑:

    1. 有一個路徑會連結至父模型的新項目。 您必須輸入路徑運算式巡覽從現有的項目,透過內嵌的關聯性父模型。 最後,它會在新的連結將會指派新的項目中指定的角色。 路徑如下所示:

      ExampleModelHasElements.ExampleModel/!ExampleModel/.Elements

    2. 在另一個路徑連結新的項目至現有的項目。 路徑運算式會指定參考關聯性和新的項目將被指派的角色。 這個路徑如下所示:

      ExampleElementReferencesTargets.Sources

    您可以使用 [路徑] 瀏覽工具來建立每個路徑:

    1. 藉由建立在路徑的連結的處理程序合併,按一下 [ < 新增路徑 >

    2. 按一下 [清單項目] 旁的下拉箭號]。 會出現樹狀檢視。

    3. 展開的節點在樹狀目錄中,以組成您想要指定的路徑。

  5. 測試 DSL:

    1. 按 F5 以重新建置並執行方案。

      重建將會比平常更長的時間,因為產生的程式碼將會更新以符合新的 DSL 定義文字範本。

    2. 當實驗性的執行個體的Visual Studio已經啟動,請開啟您的 DSL 模型檔。 建立一些範例項目。

    3. 自 [ 範例項目工具拖曳到現有的圖形。

      新的圖形看起來像是,與它連結到現有的圖形與連接器。

    4. 複製現有的圖案。 選取另一個圖形並貼上。

      會建立一份的第一個圖案。 它有新的名稱,然後它連結到第二個圖形的連接線。

請注意此程序中的下列各點:

  • 藉由建立項目合併的指示詞,您可以允許任何類別,以接受任何其他的項目。 EMD 會在接收端的網域類別,且公認的網域類別指定在索引類別欄位。

  • 藉由定義的路徑,您可以指定哪些連結應該用來連接新的項目至現有的模型。

    您指定的連結應該包含一個內嵌的關聯性。

  • EMD 會影響這兩種建立,並也貼上作業。

    如果您撰寫自訂程式碼,就會建立新的元素時,您可以明確地 EMD 使用叫用ElementOperations.Merge方法。 如此可確保您的程式碼連結新元素至模型的相同方式與其他作業。 如需詳細資訊,請參閱 自訂複製行為

範例: 加入 EMD 自訂接受的程式碼

加入 EMD 自訂程式碼,您可以定義更複雜的合併行為。 這個簡單的範例會防止使用者從多個固定數目的項目新增至圖表。 範例會修改預設隨附於內嵌的關聯性的 EMD。

若要撰寫自訂接受以限制使用者可以新增的程式碼

  1. 藉由建立 DSL 降到最低的語言方案範本。 開啟 DSL 定義圖表。

  2. 在 DSL 總管] 中,展開網域類別, ExampleModel, 項目合併的指示詞。 選取項目合併指示詞,名為ExampleElement。

    這個 EMD 控制使用者如何建立新ExampleElement在模型中,例如藉由從工具箱拖曳物件。

  3. DSL 詳細資料 視窗中,選取 使用自訂接受

  4. 重建方案。 這將耗費更長的時間比平常,因為產生的程式碼將會從模型中更新。

    建置錯誤會報告,就像: 「Company.ElementMergeSample.ExampleElement不會包含定義CanMergeExampleElement…"

    您必須實作的方法CanMergeExampleElement。

  5. 建立新的程式碼檔,在 Dsl 專案。 它的內容取代成下列程式碼,並變更至您專案的命名空間的命名空間。

    using Microsoft.VisualStudio.Modeling;
    
    namespace Company.ElementMergeSample // EDIT.
    {
      partial class ExampleModel
      {
        /// <summary>
        /// Called whenever an ExampleElement is to be merged into this ExampleModel.
        /// This happens when the user pastes an ExampleElement
        /// or drags from the toolbox.
        /// Determines whether the merge is allowed.
        /// </summary>
        /// <param name="rootElement">The root element in the merging EGP.</param>
        /// <param name="elementGroupPrototype">The EGP that the user wants to merge.</param>
        /// <returns>True if the merge is allowed</returns>
        private bool CanMergeExampleElement(ProtoElementBase rootElement, ElementGroupPrototype elementGroupPrototype)
        {
          // Allow no more than 4 elements to be added:
          return this.Elements.Count < 4;
        }
      }
    }
    

    這個簡單的範例中,會限制可以合併到父模型的元素數目。 有關更有趣的條件,方法可以檢查任一屬性,並接收物件的連結。 它也可以檢查執行中的合併項目屬性ElementGroupPrototype。 如需 ElementGroupPrototypes 的詳細資訊,請參閱 自訂複製行為。 如需有關如何撰寫會讀取一個模型的程式碼的詳細資訊,請參閱巡覽及更新程式碼中的模型

  6. 測試 DSL:

    1. 按 F5 以重新建置方案。 當實驗性的執行個體的Visual Studio便會開啟,開啟您的 DSL 的執行個體。

    2. 以數種方式建立新的項目:

      1. 自 [ 範例項目工具拖曳至圖表。

      2. 範例模型總管,以滑鼠右鍵按一下根節點,然後按一下 Add 範例項目

      3. 複製並貼到圖表上的項目。

    3. 請確認您不能使用任何這些方法,可將四個以上的項目加入至模型。 這是因為它們都是使用元素合併指示詞。

範例: 將自訂合併的程式碼加入至 EMD

在自訂合併程式碼中,您可以定義當使用者拖曳一種工具,或貼到項目時,會發生什麼事。 有兩種方式來定義自訂合併:

  1. 設定會使用自訂合併 ,並提供必要的程式碼。 您的程式碼取代產生的合併列印的程式碼。 如果您想要完全重新定義合併做了什麼,請使用此選項。

  2. 覆寫MergeRelate方法,並選擇性地MergeDisconnect方法。 若要這樣做,您必須設定會產生雙衍生網域類別的屬性。 您的程式碼可以呼叫產生的合併列印的程式碼基底類別中。 如果您想要執行其他作業,執行合併後,請使用此選項。

這種方法只會影響使用此 EMD 所執行的合併。 如果您想要會影響所有的方法,可以在其中建立合併的項目,還可以定義AddRule上內嵌的關聯性和DeleteRule合併的網域類別上。 如需詳細資訊,請參閱規則傳播模型內的變更

若要覆寫 MergeRelate

  1. 在 DSL 定義中,請確定您已定義您要加入程式碼的 EMD。 如果您想要的選項,您可以加入路徑,並定義自訂接受程式碼,如前面章節所述。

  2. 在 DslDefinition 圖表中,選取 [接收合併的類別。 通常是在原始檔的結尾內嵌的關聯性類別。

    比方說,在 DSL,產生最少的語言方案中,選取 [ ExampleModel。

  3. 屬性 ] 視窗中,設定 會產生雙衍生,則為 true

  4. 重建方案。

  5. 檢查內容的Dsl\Generated Files\DomainClasses.cs。 搜尋方法命名為MergeRelate ,並檢查其內容。 這將幫助您撰寫您自己版本的項目。

  6. 在新的程式碼檔案,寫入接收的類別,會以部分類別並覆寫MergeRelate方法。 請務必呼叫基底方法。 例如:

      partial class ExampleModel
      {
        /// <summary>
        /// Called when the user drags or pastes an ExampleElement onto the diagram.
        /// Sets the time of day as the name.
        /// </summary>
        /// <param name="sourceElement">Element to be added</param>
        /// <param name="elementGroup">Elements to be merged</param>
        protected override void MergeRelate(ModelElement sourceElement, ElementGroup elementGroup)
        {
          // Connect the element according to the EMD:
          base.MergeRelate(sourceElement, elementGroup);
    
          // Custom actions: 
          ExampleElement mergingElement = sourceElement as ExampleElement;
          if (mergingElement != null)
          {
            mergingElement.Name = DateTime.Now.ToLongTimeString();
          }
        }
      }
    

若要撰寫自訂合併的程式碼

  1. Dsl\Generated Code\DomainClasses.cs,檢查方法命名為MergeRelate。 這些方法會建立新的項目與現有的模型之間的連結。

    此外,檢查方法命名為MergeDisconnect。 它會被刪除時,這些方法取消連結從模型項目。

  2. DSL 總管、 選取或建立指示項目合併詞您想要自訂。 在 DSL 詳細資料 ] 視窗中,設定 會使用自訂合併

    當您設定這個選項時, 合併處理程序向前合併選項都會被忽略。 您的程式碼會使用。

  3. 重建方案。 花費較長的時間比平常因為產生的程式碼檔案將會從模型中更新。

    會出現錯誤訊息。 連按兩下錯誤訊息,以查看產生的程式碼中的指示進行。 這些指示,請要求您提供兩種方法, MergeRelateYourDomainClass 和MergeDisconnectYourDomainClass

  4. 在方法中撰寫個別程式碼檔案的部分類別定義。 應該建議您檢查先前的範例,您的需要。

自訂合併程式碼並不會影響程式碼會直接建立物件和關聯性,並不會影響其他的 EMDs。 若要確認是否已經無論建立的項目是如何實作了其他變更,請考慮撰寫AddRule和DeleteRule相反。 如需詳細資訊,請參閱規則傳播模型內的變更

將合併作業的重新導向

順向的合併列印的指示詞會重新導向為合併作業的目標。 一般而言,新的目標是內嵌的父代的初始目標。

比方說,使用 [元件圖表] 範本所建立的 DSL 在連接埠被內嵌在元件。 連接埠會顯示成小的圖形,在 [元件] 圖形的邊緣上。 使用者建立連接埠] 工具拖曳到元件圖形的連接埠。 但某些情況下,使用者不小心拖連接埠] 工具的元件,而不是現有連接埠,而且作業將會失敗。 如果有數個現有的連接埠,這會很容易發生錯誤。 為了要避免這個討厭的使用者,您可以允許連接埠,以將它們拖曳至現有的連接埠,但已被重新導向至父元件的動作。 作業的運作方式如同目標項目是該元件。

您可以建立正向合併指示詞元件模型方案中。 如果您編譯並執行原始的方案時,您應該會看到使用者可以拖曳任何數目的的輸入連接埠輸出連接埠 中的項目 工具箱元件項目。 不過,他們也無法將連接埠拖曳至現有的連接埠。 無法使用的指標會提醒他們在此動作不會啟用。 不過,建立正向合併指示詞,使連接埠,是因為不小心卸除現有的輸入連接埠 轉送到 元件項目。

若要建立正向合併指示詞

  1. 建立Domain-Specific Language Tools藉由使用 [元件模型] 範本的解決方案。

  2. 顯示 DSL 總管開啟 DslDefinition.dsl。

  3. DSL 總管,展開 網域類別

  4. ComponentPort 定義域抽象類別是基底類別,兩者的 InPortOutPort。 以滑鼠右鍵按一下 ComponentPort ,然後按一下 [ 加入新項目合併指引

    項目合併的指示詞 節點就會出現在 項目合併的指示詞節點。

  5. 選取 [ 項目合併的指示詞 節點,並開啟 DSL 詳細資料視窗。

  6. 在 [編製索引的 [類別] 清單中選取 ComponentPort

  7. 選取 [ 轉寄至不同的網域類別合併

  8. 在 [路徑] 選取項目清單中,展開 ComponentPort,展開 ComponentHasPorts,然後選取 元件

    新的路徑應該看起來像這樣:

    ComponentHasPorts.Component/!元件

  9. 儲存方案,] 與 [然後轉換範本,最右邊的按鈕,即可方案總管] 中工具列。

  10. 建置並執行方案。 新的執行個體的Visual Studio就會出現。

  11. 方案總管] 中,開啟 Sample.mydsl。 圖表和 ComponentLanguage 工具箱會出現。

  12. 拖曳的輸入連接埠工具箱到另一個 輸入連接埠 接著,您可以拖曳 OutputPortInputPort ,然後與另一個 OutputPort

    就不會看到無法使用的指標,而且您應該要能夠拖放新的輸入連接埠上現有的平台。 選取新的的輸入連接埠 ,並將其拖曳到另一個點 元件

請參閱

概念

巡覽及更新程式碼中的模型

自訂工具和工具箱

其他資源

電路圖表範例 DSL