Navigace v modelu a aktualizace modelu v kódu programu
Můžete napsat kód, vytvoření a odstranění prvků modelu, nastavit jejich vlastnosti a vytvořit a odstranit propojení mezi prvky.Všechny změny se musí provést v rámci transakce.Jestliže jsou prvky diagramu, diagramu "stanovenou" automaticky na konci transakce.
V tomto tématu
Definici například DSL
Model navigace
Přístup k informacím třídy
Provést změny uvnitř transakce
Vytváření prvků modelu
Vytváření vztahu odkazy
Odstranění prvků
Odstranění propojení vztah
Změna pořadí odkazů vztah
Zámky
Kopírování a vkládání
Navigace a aktualizaci diagramy
Navigace mezi obrazci a prvky
Vlastnosti obrazců a spojnic
DocView a DocData
Tvary, konektory a diagramy a jejich vztahy s prvky modelu jsou popsány v samostatné téma.Další informace naleznete v tématu [přesměrovat] Postupy: Navigace v diagramu a aktualizace diagramu.
Definici například DSL
Toto je hlavní část DslDefinition.dsl příklady v tomto tématu:
Tento model je instance této DSL:
Odkazy a obory názvů
Chcete-li spustit kód v tomto tématu, by měl referenční:
Microsoft.VisualStudio.Modeling.Sdk.11.0.dll
Kód bude používat tento obor názvů:
using Microsoft.VisualStudio.Modeling;
Kromě toho psaní kódu jiného projektu, než ve kterém je definován v DSL byste importovat sestavení, který je součástí projektu Dsl.
Model navigace
Vlastnosti
Vlastnosti domény, které definujete v definici DSL stát vlastnosti, které lze v kódu programu:
Person henry = ...;
if (henry.BirthDate < 1500) ...
if (henry.Name.EndsWith("VIII")) ...
Pokud chcete nastavit vlastnost, je nutné je uvnitř transakce:
henry.Name = "Henry VIII";
Pokud DSL definice, vlastnosti a druhu je vypočtené, nelze nastavit.Další informace naleznete v tématu Vypočtené a vlastní vlastnosti úložiště.
Vztahy
Domény vztahů, které definujete v definici DSL se dvojice vlastností, jeden na každém konci vztah třídy.Názvy vlastností se v diagramu DslDefinition jako popisky na role na každé straně relace.V závislosti na násobnost roli je typ vlastnosti třídy na konci vztah nebo kolekce této třídy.
foreach (Person child in henry.Children) { ... }
FamilyTreeModel ftree = henry.FamilyTreeModel;
Vždy jsou vlastnosti na protilehlých koncích vztah vzájemné.Po vytvoření nebo odstranění odkazu vlastnosti role oba prvky jsou aktualizovány.Následující výraz (který používá příponu System.Linq) platí vždy pro vztah ParentsHaveChildren Příklad:
(Person p) => p.Children.All(child => child.Parents.Contains(p))
&& p.Parents.All(parent => parent.Children.Contains(p));
ElementLinks.Vztah je reprezentován prvku modelu se nazývá také odkaz, což je instance vztahu typu domény.Odkaz má vždy jeden zdroj prvku a jeden cílový prvek.Prvek zdrojový a cílový prvek může být stejné.
Přístup odkaz a jeho vlastnosti:
ParentsHaveChildren link = ParentsHaveChildren.GetLink(henry, edward);
// This is now true:
link == null || link.Parent == henry && link.Child == edward
Více než jedna instance vztahu je ve výchozím nastavení povoleno propojit jakýkoli pár prvky modelu.Ale pokud v definici DSL Allow Duplicates příznak platí vztah, pak může být více než jedno propojení a je nutné použít GetLinks:
foreach (ParentsHaveChildren link in ParentsHaveChildren.GetLinks(henry, edward)) { ... }
Existují také jiné metody přístupu k propojení.Příklad:
foreach (ParentsHaveChildren link in ParentsHaveChildren.GetLinksToChildren(henry)) { ... }
Skryté role. Pokud v definici DSL Vlastnost je generován je false pro určitou roli, pak žádná vlastnost generují odpovídající dané role.Můžete však stále přístup k propojení a křížovou odkazy pomocí metod vztah:
foreach (Person p in ParentsHaveChildren.GetChildren(henry)) { ... }
Je nejčastěji používaných například PresentationViewsSubject vztah, který odkazuje prvek modelu na tvar, který se zobrazí v diagramu:
PresentationViewsSubject.GetPresentation(henry)[0] as PersonShape
V adresáři prvku
Chcete-li získat přístup všechny prvky v úložišti služby directory prvek:
store.ElementDirectory.AllElements
Existují také způsobů hledání prvky, jako například:
store.ElementDirectory.FindElements(Person.DomainClassId);
store.ElementDirectory.GetElement(elementId);
Přístup k informacím třídy
Můžete získat informace o třídách, vztahy a další aspekty definice DSL.Příklad:
DomainClassInfo personClass = henry.GetDomainClass();
DomainPropertyInfo birthProperty =
personClass.FindDomainProperty("BirthDate")
DomainRelationshipInfo relationship =
link.GetDomainRelationship();
DomainRoleInfo sourceRole = relationship.DomainRole[0];
Tříd prvků modelu jsou následující:
ModelElement - všechny prvky a vztahy jsou ModelElements
ElementLink - ElementLinks jsou všechny vztahy
Provést změny uvnitř transakce
Změně kódu programu nic v úložišti, je nutné uvnitř transakce.To platí pro všechny prvky modelu, vztahy, tvary, diagramy a jejich vlastnosti.Další informace naleznete v tématu Transaction.
Je nejpohodlnější způsob správy transakce se using prohlášení uzavřený v try...catch prohlášení:
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.
}
Můžete vytvořit libovolný počet změn v rámci jedné transakce.Můžete otevřít nové transakce uvnitř aktivní transakce.
Chcete-li změny trvalé, Commit transakcí, než je uvolněn.Pokud dojde k výjimce není zachycené uvnitř transakce, bude úložiště obnovit do stavu před změny.
Vytváření prvků modelu
Tento příklad přidá prvek do existujícího modelu:
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!
}
Tento příklad ukazuje tyto základní body o vytváření prvku:
Vytvořte nový prvek v konkrétním oddílu úložiště.Pro prvky modelu a vztahy, ale není obrazců je to obvykle výchozí oddíl.
Vytvořit cíl vkládání vztah.DslDefinition-li tento příklad musí být každá osoba cíl vkládání vztah FamilyTreeHasPeople.K dosažení tohoto jsme nastavit vlastnost FamilyTreeModel roli objektu osoba nebo osoby přidat roli lidé vlastnosti objektu FamilyTreeModel.
Nastavit vlastnosti nového prvku, zejména vlastnosti, které IsName je v DslDefinition hodnotu true.Tento příznak označuje vlastnost, která slouží k identifikaci jednoznačně prvku jeho vlastníkem.V tomto případě vlastnost název má tento příznak.
Definice této DSL DSL musí byl načten do úložiště.Pokud vytváříte rozšíření jako příkaz nabídky, obvykle je již hodnotu true.V ostatních případech můžete explicitně načtení modelu do úložiště nebo pomocí ModelBus ji načíst.Další informace naleznete v tématu Postupy: Otevření modelu ze souboru v kódu programu.
Tímto způsobem vytvoříte element, obrazce automaticky vytvořen (Pokud modem DSL má diagramu).Zobrazí v automaticky přiřazené umístění výchozí tvar, barvu a další funkce.Chcete-li určit, kde a jak se zobrazí přidružený tvar, viz vytvoření prvku a jeho tvar.
Vytváření vztahu odkazy
Existují dvě relace definované v příkladu definice DSL.Definuje každý vztah Vlastnosti role na třídě na každém konci vztah.
Instance vztahu lze vytvořit třemi způsoby.Každá z těchto tří metod má stejný účinek:
Vlastnost zdroj role přehrávače.Příklad:
familyTree.People.Add(edward);
edward.Parents.Add(henry);
Vlastnost cílové role přehrávače.Příklad:
edward.familyTreeModel = familyTree;
Násobnost této role je 1..1, takže můžeme přiřadit hodnotu.
henry.Children.Add(edward);
Násobnost této role je 0..*, takže můžeme přidat do kolekce.
Vytvořte instance vztahu explicitně.Příklad:
FamilyTreeHasPeople edwardLink = new FamilyTreeHasPeople(familyTreeModel, edward);
ParentsHaveChildren edwardHenryLink = new ParentsHaveChildren(henry, edward);
Poslední metoda je užitečná, chcete-li nastavit vlastnosti samotnou relaci.
Tímto způsobem vytvoříte element, spojnice v diagramu je automaticky vytvořen, ale má výchozí tvar, barvu a další funkce.Ovládat způsob vytvoření přidruženého konektor, naleznete v tématu vytvoření prvku a jeho tvar.
Odstranění prvků
Odstranění prvku voláním Delete():
henry.Delete();
Tato operace odstraní:
Vztah odkazů a v prvku.Například edward.Parents bude obsahovat již henry.
Prvky na role, pro které PropagatesDelete příznak hodnotu true.Například obrazec, který zobrazí prvek bude odstraněn.
Standardně má každý vztah vkládání PropagatesDelete hodnotu true na cílovou roli.Odstranění henry neodstraní familyTree, ale familyTree.Delete() by odstranit všechny Persons.Další informace naleznete v tématu Přizpůsobení chování odstranění.
Ve výchozím nastavení PropagatesDelete není pro role vztahů referenční hodnotu true.
Může způsobit odstranění pravidla vynechat určitý šíření při odstranění objektu.To je užitečné, pokud jsou nahrazení jednoho prvku jiným.Můžete zadat identifikátor GUID jedné nebo více rolí, jejichž odstranění by předány.Identifikátor GUID lze získat z třídy vztah:
henry.Delete(ParentsHaveChildren.SourceDomainRoleId);
(Zejména v příkladu by mít žádný vliv, protože PropagatesDelete je false u rolí ParentsHaveChildren vztah.)
V některých případech je zabránit odstranění existence zámek na prvek nebo na prvek, který by šíření odstraněn.Můžete použít element.CanDelete() zkontrolujte, zda je možné odstranit element.
Odstranění propojení vztah
Odebrání prvku z vlastnosti role můžete odstranit odkaz vztah:
henry.Children.Remove(edward); // or:
edward.Parents.Remove(henry); // or:
Propojení můžete také odstranit explicitně:
edwardHenryLink.Delete();
Tyto tři metody, všechny mají stejný účinek.Potřebujete použít jeden z nich.
Pokud má role násobnost 0..1 nebo 1..1, je možné ji nastavit null, nebo na jinou hodnotu:
edward.FamilyTreeModel = null;/ / nebo:
edward.FamilyTreeModel = anotherFamilyTree;
RE-Ordering odkazy vztah
Odkazy zejména vztah, který je získání nebo zaměřený na konkrétní model prvek mít určité sekvence.Jsou zobrazeny v pořadí, v jakém byly přidány.Tento příkaz například povede vždy děti ve stejném pořadí:
foreach (Person child in henry.Children) ...
Můžete změnit pořadí odkazů:
ParentsHaveChildren link = GetLink(henry,edward);
ParentsHaveChildren nextLink = GetLink(henry, elizabeth);
DomainRoleInfo role =
link.GetDomainRelationship().DomainRoles[0];
link.MoveBefore(role, nextLink);
Zámky
Změny mohou být zabránit uzamčení.Zámky lze nastavit na jednotlivých prvků, oddílů a úložiště.Pokud má některé z těchto úrovní zámek, který zabraňuje druh změn, které chcete provést, může při pokusu o jeho vyvolání výjimky.Můžete zjistit, zda jsou pomocí prvku nastavit uzamčení.GetLocks(), což je metoda rozšíření, která je definována v Immutability.
Další informace naleznete v tématu Definování zásady zamykání pro vytváření segmentů jen pro čtení.
Kopírování a vkládání
Můžete kopírovat prvky nebo skupiny prvků 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>());
Prvky jsou uloženy jako serializované prvek skupiny.
Prvky z IDataObject lze sloučit do modelu:
using (Transaction t = targetDiagram.Store.
TransactionManager.BeginTransaction("paste"))
{
adopterShape.Diagram.ElementOperations.Merge(adopter, data);
}
Merge ()můžete přijmout PresentationElement nebo ModelElement.Pokud jej dát PresentationElement, můžete také určit pozici na terčový diagram jako třetí parametr.
Navigace a aktualizaci diagramy
DSL je odděleně od tvaru prvek, který představuje v diagramu zobrazit prvek modelu domény, což představuje pojem jako osoba nebo skladby.Prvek modelu domény ukládá důležité vlastnosti a vztahy pojmů.Obrazec prvek ukládá, velikosti, polohy a barvy objektu zobrazení do diagramu a rozložení jeho součástí.
Prvky prezentace
Každý prvek, který určíte v DSL Definition, vytvoří třídu, která je odvozena z jednoho z následujících standardních tříd.
Typ elementu |
Základní třída |
---|---|
Třída domény |
|
Vztah domény |
|
Obrazce |
|
Spojnice |
|
Diagram |
Prvek v diagramu obvykle představuje prvek modelu.Obvykle (ale ne vždy) NodeShape představuje instanci třídy domény a BinaryLinkShape představuje instanci vztah domény.PresentationViewsSubject Vztah obrazec odkaz nebo odkazy k prvku modelu, který představuje.
Každý obrazec nebo odkaz patří do jednoho diagramu.Obrazec binární propojení spojuje dva obrazce uzel.
Obrazce mohou mít podřízené obrazce dvě sady.Obrazce v NestedChildShapes sada je omezena na ohraničovací rámeček nadřazené položky.Obrazce v RelativeChildShapes zobrazení seznamu vně nebo částečně mimo hranice nadřazené – například popisek nebo port.Diagram nemá žádné RelativeChildShapes a Parent.
Navigace mezi obrazci a prvky
Prvky modelu domény a obrazce prvků se vztahují PresentationViewsSubject vztah.
// using Microsoft.VisualStudio.Modeling;
// using Microsoft.VisualStudio.Modeling.Diagrams;
// using System.Linq;
Person henry = ...;
PersonShape henryShape =
PresentationViewsSubject.GetPresentation(henry)
.FirstOrDefault() as PersonShape;
Stejný vztah odkazy na spojnice v diagramu vztahů:
Descendants link = Descendants.GetLink(henry, edward);
DescendantConnector dc =
PresentationViewsSubject.GetPresentation(link)
.FirstOrDefault() as DescendantConnector;
// dc.FromShape == henryShape && dc.ToShape == edwardShape
Tento vztah také odkazy kořenové lokalitě modelu do diagramu:
FamilyTreeDiagram diagram =
PresentationViewsSubject.GetPresentation(familyTree)
.FirstOrDefault() as FamilyTreeDiagram;
Chcete-li prvek modelu zastoupena obrazcem, použijte:
henryShape.ModelElement as Person
diagram.ModelElement as FamilyTreeModel
Navigace v diagramu
Obecně není vhodné k navigaci mezi obrazci a spojnicemi diagramu.Je lepší navigace vztahy v modelu, přesouvání mezi obrazci a spojnicemi pouze v případě, že je nutné pracovat na vzhled diagramu.Tyto metody propojení spojnice obrazců na každém konci:
personShape.FromRoleLinkShapes, personShape.ToRoleLinkShapes
connector.FromShape, connector.ToShape
Mnoho obrazců jsou složené; jsou vytvořeny nadřazeného obrazce a jednu nebo více vrstev dětí.Obrazce, které jsou umístěny jiné obrazce, které jsou označeny jako jeho děti.Při pohybu nadřazeného obrazce, přesuňte děti s ním.
Relativní děti může být mimo ohraničovací rámeček nadřazeného obrazce.Vnořené dětí se přísně uvnitř hranice nadřazené.
Chcete-li získat nejvyšší sady obrazců v diagramu, použijte:
Diagram.NestedChildShapes
Tříd obrazců a spojnic, jsou:
-- ShapeElement
----- NodeShape
------- Diagram
------- YourShape
----- LinkShape
------- BinaryLinkShape
--------- YourConnector
Vlastnosti obrazců a spojnic
Ve většině případů není nutné provést explicitní změny tvarů.Při změně prvky modelu pravidla "Opravit" aktualizace obrazců a spojnic.Další informace naleznete v tématu Reagování na změny a šíření změn.
Je vhodné provést některé změny explicitní obrazce v dialogovém okně Vlastnosti, které jsou nezávislé na prvky modelu.Nelze například změnit tyto vlastnosti:
Size-Určuje výšku a šířku obrazce.
Location-polohy nadřazeného obrazce nebo diagramu
StyleSet-Sada per a stopy pro kreslení tvaru nebo konektor
Hide-vytvoří obrazec neviditelné
Show-zviditelní po obrazceHide()
Vytvoření prvku a jeho tvar
Po vytvoření prvku a propojení do stromu vložení vztahů obrazce je automaticky vytvořen a s ním spojené.Důvodem je "opravu" pravidla, která na konci transakce provést.Obrazec se zobrazí v automaticky přiřazeno umístění a jeho tvar, barvu a další funkce budou mít výchozí hodnoty.Chcete-li ovládat způsob vytvoření tvaru, můžete použít funkci hromadné korespondence.Nejprve přidat prvky, které chcete přidat do ElementGroup a skupiny sloučit diagramu.
Tato metoda:
Nastaví název, pokud jste přiřadili vlastnost jako název prvku.
Dodržuje libovolný prvek sloučení směrnic zadané v definici DSL.
Tento příklad vytvoří tvar pozice myši, když uživatel poklepe diagramu.V definici pro tuto ukázku DSL FillColor vlastnost ExampleShape byli exponováni.
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();
}
}
}
Pokud zadáte více obrazců, nastavit jejich relativní polohy pomocí AbsoluteBounds.
Můžete také nastavit barvu a další ohrožené vlastnosti spojnice pomocí této metody.
Použití transakce
Tvary, konektory a diagramy jsou podtypy ModelElement a živé v úložišti.Proto je nutné provést změny na ně pouze uvnitř transakce.Další informace naleznete v tématu Postupy: Používání transakcí k aktualizaci modelu.
Zobrazení dokumentů a dat dokumentu
Oddíly úložiště
Při načtení modelu diagramu průvodní načten současně.Obvykle modelu je načten do Store.DefaultPartition a obsah diagramu je načten do jiného oddílu.Obvykle obsah jednotlivých oddílů načíst a uložit do samostatného souboru.
Viz také
Referenční dokumentace
Koncepty
Ověřování v jazyce specifickém pro doménu
Postupy: Používání transakcí k aktualizaci modelu
Integrace modelů pomocí Visual Studio Modelbus