共用方式為


您可以撰寫程式碼來建立和刪除模型元素、 設定其屬性,並建立及刪除項目間的連結。 必須在交易內進行的所有變更。 如果在圖表上所看到的項目,圖表將會 「 」 自動修正交易結尾處。

本主題內容

範例 DSL 定義

瀏覽模型

存取類別資訊

執行在交易內的變更

建立模型項目

建立關聯性連結

刪除項目

刪除關聯性連結

重新調整順序關聯性的連結

鎖定

複製和貼上

瀏覽及更新圖表

圖形和項目之間巡覽

圖案及連接線的內容

DocView 和 DocData

圖形、 連接器與圖表中,與模型元素的關聯性不同的主題所述。 如需詳細資訊,請參閱 [重新導向] HOW TO:巡覽及更新圖表

範例 DSL 定義

這是 DslDefinition.dsl 的主要部分,如本主題中的範例:

DSL 定義圖表 - 家譜模型

這種模型是此 DSL 的執行個體:

都鐸王朝家譜模型

Cc512845.collapse_all(zh-tw,VS.110).gif參考和命名空間

若要執行本主題中的程式碼,您應該參考:

Microsoft.VisualStudio.Modeling.Sdk.11.0.dll

您的程式碼會使用這個命名空間:

using Microsoft.VisualStudio.Modeling;

此外,如果您正在撰寫的程式碼中用來定義您的 DSL 與不同的專案,您應該匯入的 Dsl 專案所建置的組件。

瀏覽模型

Cc512845.collapse_all(zh-tw,VS.110).gif屬性

您的 DSL 定義中定義的網域內容屬性會成為您即可存取程式碼中:

Person henry = ...;

if (henry.BirthDate < 1500) ...

if (henry.Name.EndsWith("VIII")) ...

若您想要設定屬性,您必須進行內部交易:

henry.Name = "Henry VIII";

If DSL 定義中,屬性的計算,您不能設定它。 如需詳細資訊,請參閱 計算及自訂的儲存區屬性

Cc512845.collapse_all(zh-tw,VS.110).gif關聯性

您的 DSL 定義中定義的網域關聯性會變得成對的另一個在每一端的關聯性類別的屬性。 屬性的名稱會出現在 DslDefinition 圖表中,為每邊的資料表在角色中的標籤。 根據角色的多樣性,屬性的型別會是關聯另一端的類別,或者是該類別的集合。

foreach (Person child in henry.Children) { ... }

FamilyTreeModel ftree = henry.FamilyTreeModel;

在關聯性屬性永遠是倒數。 當建立或刪除連結時,會更新這兩個項目上的角色屬性。 下列的運算式 (這麼做會使用的副檔名System.Linq) 永遠是 true ParentsHaveChildren 關聯性範例所示:

(Person p) => p.Children.All(child => child.Parents.Contains(p))

&& p.Parents.All(parent => parent.Children.Contains(p));

ElementLinks。 關聯性也由稱為的模型項目連結,也就是網域的關聯性型別的執行個體。 連結一律是具有一個來源項目和一個目標項目。 來源項目,且目標項目可以相同。

您可以存取連結和它的屬性:

ParentsHaveChildren link = ParentsHaveChildren.GetLink(henry, edward);

// This is now true:

link == null || link.Parent == henry && link.Child == edward

預設情況下,不能超過一個的執行個體的關聯性可連結模型項目的任何配對。 但如果在 DSL 定義中, Allow Duplicates旗標為 true 的關聯性,則可能有一個以上的連結,而且您必須使用GetLinks:

foreach (ParentsHaveChildren link in ParentsHaveChildren.GetLinks(henry, edward)) { ... }

另外還有其他方法來存取連結。 例如:

foreach (ParentsHaveChildren link in ParentsHaveChildren.GetLinksToChildren(henry)) { ... }

隱藏的角色。 如果在 DSL 定義中, 屬性就會產生,則為 false 為特定的角色,就無法使用屬性會產生對應於該角色。 不過,您仍然可以存取連結,並周遊使用關聯性的方法的連結:

foreach (Person p in ParentsHaveChildren.GetChildren(henry)) { ... }

最常使用的範例是PresentationViewsSubject關聯性,其顯示在圖表的圖形所連結的模型項目:

PresentationViewsSubject.GetPresentation(henry)[0] as PersonShape

Cc512845.collapse_all(zh-tw,VS.110).gif項目的目錄

您可以存取存放區使用的項目目錄中的所有項目:

store.ElementDirectory.AllElements

也有一些方法來尋找項目,如下所示:

store.ElementDirectory.FindElements(Person.DomainClassId);

store.ElementDirectory.GetElement(elementId);

存取類別資訊

您可以取得類別、 關聯性和 DSL 定義的其他方面的相關資訊。 例如:

DomainClassInfo personClass = henry.GetDomainClass();

DomainPropertyInfo birthProperty =

personClass.FindDomainProperty("BirthDate")

DomainRelationshipInfo relationship =

link.GetDomainRelationship();

DomainRoleInfo sourceRole = relationship.DomainRole[0];

模型項目的祖系類別如下所示:

  • ModelElement-所有的項目和關聯性是 ModelElements

  • 中繼角色的所有關聯性是 ElementLinks

執行在交易內的變更

每當您的程式碼變更時的存放區中的任何項目,就必須進行在交易內。 這適用於所有的模型項目、 關聯、 圖形、 圖表和它們的屬性。 如需詳細資訊,請參閱 Transaction

管理交易的最方便的方法是使用using陳述式放在try...catch陳述式:

Store store; ...
try
{
  using (Transaction transaction =
    store.TransactionManager.BeginTransaction("update model"))
    // Outermost transaction must always have a name.
  {
    // Make several changes in Store:
    Person p = new Person(store);
    p.FamilyTreeModel = familyTree;
    p.Name = "Edward VI";
    // end of changes to Store

    transaction.Commit(); // Don't forget this!
  } // transaction disposed here
}
catch (Exception ex)
{
  // If an exception occurs, the Store will be 
  // rolled back to its previous state.
}

您可以將任何數目的一筆交易內的變更。 您可以開啟新的交易,在使用中的交易內。

若要維持變更後的設定,請您應該Commit交易之前將它處置。 如果未攔截到在交易內發生例外狀況,所做的變更前的狀態將會重設的存放區。

建立模型項目

本範例會將元素加入至現有的模型:

FamilyTreeModel familyTree = ...; // The root of the model.       
using (Transaction t =
    familyTree.Store.TransactionManager
    .BeginTransaction("update model"))
{
  // Create a new model element 
  // in the same partition as the model root:
  Person edward = new Person(familyTree.Partition);
  // Set its embedding relationship:
  edward.FamilyTreeModel = familyTree;
          // same as: familyTree.People.Add(edward);
  // Set its properties:
  edward.Name = "Edward VII";
  t.Commit(); // Don't forget this!
}

這個範例會說明這些基本的還原點,有關建立項目:

  • 在特定的磁碟分割的儲存區中建立新的項目。 對於模型元素及其關聯性,但不是圖形,這通常是預設資料分割。

  • 請內嵌的關聯性的目標。 在這個範例的 DslDefinition,每個人都必須是內嵌 FamilyTreeHasPeople 的關聯性的目標。 若要這麼做,我們可以設定 FamilyTreeModel 角色物件的內容的人,或將此人至 FamilyTreeModel 物件的人員角色屬性。

  • 設定新的項目,特別是其屬性的屬性IsName是在 DslDefinition 中,則為 true。 這個旗標標示可識別唯一內其擁有者的項目屬性。 在此情況下,[名稱] 屬性會有該旗標。

  • DSL 的定義這個 DSL 必須載入至存放區。 如果您正在撰寫的副檔名,例如功能表命令,這通常是已經,則為 true。 在其他情況下,您可以明確地將模型載入至存放區中,或使用ModelBus載入它。 如需詳細資訊,請參閱 HOW TO:在程式碼中開啟檔案的模型

當您建立項目,如此一來時,圖形會自動建立 (如果 DSL 圖表)。 它會顯示在自動指定的位置,請使用預設的圖案、 色彩及其他功能。 如果您想要控制關聯的圖形位置和方式出現,請參閱建立的項目和形狀。

建立關聯性連結

有兩個範例 DSL 定義中所定義的關聯。 每個關係定義角色 」 屬性兩端的關聯性類別上。

有三種方式,您可以在其中建立關聯性的執行個體。 這三種方法的每個具有相同的效果:

  • 設定來源角色扮演者屬性。 例如:

    • familyTree.People.Add(edward);

    • edward.Parents.Add(henry);

  • 設定目標角色扮演者屬性。 例如:

    • edward.familyTreeModel = familyTree;

      此角色的重數是1..1,所以我們將值指派。

    • henry.Children.Add(edward);

      此角色的重數是0..*,所以我們將加入至集合。

  • 明確地建構執行個體的關聯性。 例如:

    • FamilyTreeHasPeople edwardLink = new FamilyTreeHasPeople(familyTreeModel, edward);

    • ParentsHaveChildren edwardHenryLink = new ParentsHaveChildren(henry, edward);

最後一個方法是很有用,如果您想要在本身的關聯性上設定屬性。

當您建立項目,如此一來時,在圖表上的連接器會自動建立,但它預設圖案、 色彩及其他功能。 若要控制如何建立關聯的連接器,請參閱建立的項目和形狀。

刪除項目

刪除項目,藉由呼叫Delete():

henry.Delete();

此外,也會刪除這項操作:

  • 關聯性連結,並從項目。 例如, edward.Parents不會再有henry。

  • 項目在其角色PropagatesDelete旗標為 true。 比方說,您將刪除的圖案所顯示的項目。

根據預設,每個內嵌的關聯性有PropagatesDelete在 「 目標 」 角色,則為 true。 刪除henry並不會刪除familyTree,但familyTree.Delete()會刪除所有Persons。 如需詳細資訊,請參閱 自訂刪除行為

預設情況下, PropagatesDelete不是參考關聯性的角色,則為 true。

您可能會導致略過特定的傳播,當您刪除物件的刪除規則。 這是很有用,如果以一個項目取代為另一個項目。 您提供的是,刪除不需要傳播的一或多個角色的 GUID。 您可以從關聯性類別取得 GUID:

henry.Delete(ParentsHaveChildren.SourceDomainRoleId);

(此特定範例會有任何作用,因為PropagatesDelete是false的角色的ParentsHaveChildren關聯性。)

在某些情況下,將無法刪除的項目上,或是會被傳用的項目上的鎖定存在。 您可以使用element.CanDelete()來檢查是否可以刪除的項目。

刪除關聯性連結

您可以藉由在 [角色] 屬性中移除項目刪除關聯性連結:

henry.Children.Remove(edward); // or:

edward.Parents.Remove(henry); // or:

您也可以明確地刪除這個連結:

edwardHenryLink.Delete();

所有這三種方法有相同的效果。 您只需要使用其中一個圖形。

如果角色有..1 或 1..1 的多樣性,您就可以將它設定為null,或為另一個值:

edward.FamilyTreeModel = null;/ / 或:

edward.FamilyTreeModel = anotherFamilyTree;

Re-ordering 關聯性的連結

特殊的關聯性中取得資料來源或某個特定的模型項目適用對象的連結會有特定的順序。 它們會出現在所加入的順序。 例如,下列陳述式一定會產生相同的順序中的子系:

foreach (Person child in henry.Children) ...

您可以變更連結的順序:

ParentsHaveChildren link = GetLink(henry,edward);

ParentsHaveChildren nextLink = GetLink(henry, elizabeth);

DomainRoleInfo role =

link.GetDomainRelationship().DomainRoles[0];

link.MoveBefore(role, nextLink);

鎖定

您的變更可能會無法鎖定。 個別項目、 磁碟分割,並在存放區,則可以設定鎖定。 如果這些層級的任何一種鎖,防止您想要做的修訂種類,當您試著時可能會擲回例外狀況。 您可以發現使用項目是否設定鎖定。也就是擴充方法中所定義的 GetLocks() Immutability。

如需詳細資訊,請參閱 定義鎖定原則來建立唯讀區段

複製和貼上

您可以複製項目或項目為群組IDataObject

Person person = personShape.ModelElement as Person;
Person adopter = adopterShape.ModelElement as Person;
IDataObject data = new DataObject();
personShape.Diagram.ElementOperations
      .Copy(data, person.Children.ToList<ModelElement>());

項目儲存為已序列化的項目群組。

您可將 IDataObject 中的項目合併的模型:

using (Transaction t = targetDiagram.Store.
        TransactionManager.BeginTransaction("paste"))
{
  adopterShape.Diagram.ElementOperations.Merge(adopter, data);
}

Merge ()可接受PresentationElement或ModelElement。 如果您為其指定PresentationElement,您也可以在圖表上的目標做為第三個參數指定的位置。

瀏覽及更新圖表

在 DSL、 網域模型項目,它代表一個概念,例如人員或歌曲,則是從圖形項目,表示您在圖表上所看到的個別項目。 網域模型項目儲存的重要屬性和關聯性的概念。 大小、 位置及物件的檢視,請在圖表上的色彩和其元件組件的版面配置,會將儲存的圖形項目。

Cc512845.collapse_all(zh-tw,VS.110).gif展示項目

基本圖案和項目類型的類別圖表

在您的 DSL 定義,您指定每個項目會建立一個衍生自下列的標準類別其中一項的類別。

只用此項

基底類別

網域類別

ModelElement

網域關聯性

ElementLink

圖案

NodeShape

連接器

BinaryLinkShape

圖表

Diagram

在圖表上的項目通常代表了模型項目。 通常 (但不是一定), NodeShape代表網域類別執行個體,以及BinaryLinkShape代表網域關聯性執行個體。 PresentationViewsSubject關聯性連結節點] 或 [連結的圖形,至其所代表的模型項目。

每一個節點] 或 [連結] 圖形是屬於一個圖表。 二進位連結] 圖形會連接兩個 [節點] 圖形。

圖形可以有兩個集合中的子圖案。 在圖形NestedChildShapes集僅限於其父代的週框方塊。 在圖形RelativeChildShapes可以顯示清單外或部分之父代 – 例如標籤或連接埠範圍外。 圖表沒有RelativeChildShapes ,並沒有Parent。

Cc512845.collapse_all(zh-tw,VS.110).gif圖形和項目之間巡覽

網域模型項目和圖形項目具有關聯性的PresentationViewsSubject關聯性。

// using Microsoft.VisualStudio.Modeling;
// using Microsoft.VisualStudio.Modeling.Diagrams;
// using System.Linq;
Person henry = ...;
PersonShape henryShape = 
  PresentationViewsSubject.GetPresentation(henry)
    .FirstOrDefault() as PersonShape;

相同的關聯性連結關係到圖表上的連接器:

Descendants link = Descendants.GetLink(henry, edward);
DescendantConnector dc =
   PresentationViewsSubject.GetPresentation(link)
     .FirstOrDefault() as DescendantConnector;
// dc.FromShape == henryShape && dc.ToShape == edwardShape

此關聯性也會介紹到圖表的模型的根:

FamilyTreeDiagram diagram = 
   PresentationViewsSubject.GetPresentation(familyTree)
      .FirstOrDefault() as FamilyTreeDiagram;

若要取得的圖案所代表的模型項目,請使用:

henryShape.ModelElement as Person

diagram.ModelElement as FamilyTreeModel

Cc512845.collapse_all(zh-tw,VS.110).gif在圖表上到處巡覽

通常不建議瀏覽不同的圖形] 及 [在圖表上的連接線。 最好是以瀏覽在模型中,就必須處理圖表的外觀時,只移動圖形與連接器之間的關聯性。 這些方法會連結至圖形,在每一端的連接器:

personShape.FromRoleLinkShapes, personShape.ToRoleLinkShapes

connector.FromShape, connector.ToShape

許多圖形都是複合型。 它們是由一個父圖案和一或多個圖層的子系所組成。 位於相對於另一個圖形的圖形可以說是其子系。 當父系圖形移動時,會隨著移動子系。

相對的子系到上層圖形的週框方塊外可能會出現。 巢狀結構子系出現嚴格之父代的界限內。

若要取得上的一組圖形在圖表上,請使用:

Diagram.NestedChildShapes

祖系的類別圖案及連接線如下:

ModelElement

-- PresentationElement

-- ShapeElement

----- NodeShape

------- Diagram

------- YourShape

----- LinkShape

------- BinaryLinkShape

--------- YourConnector

Cc512845.collapse_all(zh-tw,VS.110).gif圖案及連接線的內容

在大部分的情況下,不需要對圖形進行明確的變更。 當您變更模型項目時,「 修正 」 的規則會更新圖案及連接線。 如需詳細資訊,請參閱 回應及傳播變更

不過,很好用,無法對一些明確的模型項目無關的內容中的圖形。 例如,您可以變更這些屬性:

  • Size-決定圖形的寬度與高度。

  • Location-相對於父圖案或圖表的位置

  • StyleSet-一筆和筆刷用來繪製連接器的圖形組

  • Hide-使圖形不可見

  • Show-使圖形之後,您可以看到Hide()

Cc512845.collapse_all(zh-tw,VS.110).gif建立項目和形狀

當您建立項目,並將它連結到內嵌的關聯性的樹狀結構時,圖形會自動建立及與其相關聯。 這是由交易結尾處執行 「 修復 」 規則。 不過,圖形會出現在可自動指定的位置,並且的形狀、 色彩及其他功能將會有預設值。 若要控制圖形的建立方式,您可以使用 merge 函式。 必須先新增您想要將 ElementGroup 中,加入的項目,然後再合併到圖表中的 [群組。

這個方法可以:

  • 設定的名稱,如果您指派的項目名稱的屬性。

  • 會遵守任何項目合併的指示詞在 DSL 定義中所指定。

當使用者按兩下圖表,本範例會建立一個圖案滑鼠位置。 在這個範例中,DSL 定義FillColor屬性的ExampleShape遭受。

  using Microsoft.VisualStudio.Modeling;
  using Microsoft.VisualStudio.Modeling.Diagrams;
  partial class MyDiagram
  {
    public override void OnDoubleClick(DiagramPointEventArgs e)
    {
      base.OnDoubleClick(e);

      using (Transaction t = this.Store.TransactionManager
          .BeginTransaction("double click"))
      {
        ExampleElement element = new ExampleElement(this.Store);
        ElementGroup group = new ElementGroup(element);
         
        { // To use a shape of a default size and color, omit this block.
          ExampleShape shape = new ExampleShape(this.Partition);
          shape.ModelElement = element;
          shape.AbsoluteBounds = new RectangleD(0, 0, 1.5, 1.0);
          shape.FillColor = System.Drawing.Color.Azure;
          group.Add(shape);
        }

        this.ElementOperations.MergeElementGroupPrototype(
          this,
          group.CreatePrototype(),
          PointD.ToPointF(e.MousePosition));
        t.Commit();
      }
    }
  }

如果您提供多個圖案,設定其使用的相對位置AbsoluteBounds。

您也可以設定的色彩和連接器使用此方法的其他公開的屬性。

Cc512845.collapse_all(zh-tw,VS.110).gif使用交易

圖形、 連接器與圖表的子類型的ModelElement與實況存放區中。 因此,您必須完成這些變更只會在交易內。 如需詳細資訊,請參閱 HOW TO:使用交易更新模型

文件檢視和文件資料

標準圖表類型的類別圖表

存放區的磁碟分割

載入模型時,都會在此同時載入伴隨的圖表。 一般而言,模型載入至 Store.DefaultPartition,而且圖表內容載入至另一個磁碟分割。 通常,每個資料分割的內容載入並儲存到不同的檔案。

請參閱

參考

ModelElement

概念

網域指定的語言中的驗證

HOW TO:使用交易更新模型

使用 Visual Studio Modelbus 整合模型

其他資源

從網域指定的語言產生程式碼

回應及傳播變更