Перемещение по модели и обновление модели в коде программы
Можно написать код для создания и удаления элементов модели, задавать их свойства и создания и удаления связей между элементами.Все изменения необходимо выполнять в рамках транзакции.Если элементы, отображаемые на схеме, то будет исправлена схема "вверх" автоматически в конце транзакции.
Содержание раздела
Определение DSL примера
Перемещение модель
Доступ к данным класса
Выполните изменения в транзакции
Создание элементов модели
Создание отношения связей
Удаление элементов
Удаление отношения связей
Переупорядочение ссылки на связи
Блокирует
Копировать и вставить
Навигация по и обновление схемы
Перемещаться между фигурами и элементами
Свойства фигур и соединителей
DocView и DocData
Фигуры соединители и схемы, и их отношения к элементам модели описаны в отдельном разделе.Дополнительные сведения см. в разделе [перенаправление] Практическое руководство. Перемещение по схеме и ее обновление.
Определение DSL примера
Это основной части DslDefinition.dsl примеры в этом разделе:
Эта модель экземпляр этого DSL:
Ссылки и пространства имен
Чтобы запустить код в этом разделе, должны ссылаться на:
Microsoft.VisualStudio.Modeling.Sdk.11.0.dll
Код будет использовать это пространство имен:
using Microsoft.VisualStudio.Modeling;
Кроме того, при написании кода в другом проекте из одного, в котором определен данный DSL, нужно импортировать сборку, которая построена проектом Dsl.
Перемещение модель
Свойства
Свойства домена, указанные в определении DSL становятся свойствами, которые можно открыть в программном коде:
Person henry = ...;
if (henry.BirthDate < 1500) ...
if (henry.Name.EndsWith("VIII")) ...
Если нужно задать свойство, необходимо сделать in a транзакция.
henry.Name = "Henry VIII";
Если в определении DSL, свойство Тип существует CALCULATEDнельзя задать его.Дополнительные сведения см. в разделе Вычисляемые и пользовательские свойства хранилища.
Связи
Доменные связи, определенные в определении 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
Каталог элемента
Можно получить доступ к все элементы в хранилище, используя каталог элемента:
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
ElementLink - все связи ElementLinks
Выполните изменения в транзакции
Если программный код изменяет никаких действий в хранилище, он должен сделать внутри транзакции.Это применяется ко всем элементам модели связей, фигурам, схемам и их свойствами.Дополнительные сведения см. в разделе Transaction.
Самый удобный метод управления транзакция с a using выписка, заключенная в a 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 или роль объекта person или добавьте пользователя к роли свойства объекта FamilyTreeModel лица.
Установка свойств нового элемента, в частности, для которого свойство IsName значение true в DslDefinition.Этот пометить помечает свойство, которое служит для указания элемент уникальным в пределах его владелец.В этом случае свойство name имеет один пометить.
Определение DSL этого DSL должна быть загружена в хранилище.При написании расширение как команды меню, как правило, это будет уже имеет значение true.В других случаях можно явно загрузить модель в хранилище или использование ModelBus загрузить ее.Дополнительные сведения см. в разделе Практическое руководство. Открытие модели из файла в коде программы.
При создании элемент таким образом, форма создается автоматически, если имеет схему (DSL).Она появляется в автоматически присвоенное местоположение с формой по умолчанию, основным цветом и другими функциями.При необходимости контроля, где и как связанная форма отображается см. в разделе Создание элемента и его форма.
Создание отношения связей
2 Связи, указанного в определении DSL примера.Каждое отношение определяет a роль свойства в классе на каждом конце связи.
3 Способа в котором можно создать экземпляр связи.Каждый из этих методов 3 имеет тот же эффект:
Установите свойство роли проигрывателя источника.Примеры.
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 не выполнены для ролей связей ссылок.
Можно вызвать, чтобы исключить определенные правила удаления распространения при удалении объекта.Это полезно, если соответствующее один элемент для других.Указывается идентификатор GUID одного или нескольких ролей, для которых удаление не должно быть распространяются.Идентификатор GUID можно получить из класса отношений.
henry.Delete(ParentsHaveChildren.SourceDomainRoleId);
(Этот указанный пример не будет иметь эффекта, поскольку PropagatesDelete существует false для ролей ParentsHaveChildren связь.)
В некоторых случаях удаление запрещено существованием блокировки или на элементе или в элементе, который будет удален распространением.Можно использовать element.CanDelete() проверить, является ли элемент может быть удален.
Удаление отношения связей
Можно удалить ссылку связи путем удаления элемента из роли свойства:
henry.Children.Remove(edward); // or:
edward.Parents.Remove(henry); // or:
Можно также удалять ссылки явным образом:
edwardHenryLink.Delete();
Все эти 3 метода имеют один и тот же результат.Нужно только с помощью одного из них.
Если роль имеет 0..1 или 1..1 количества элементов необходимо присваивать ему значение nullили к другому значению.
edward.FamilyTreeModel = null; //or:
edward.FamilyTreeModel = anotherFamilyTree;
Переупорядочение ссылки на связи
Связи определенной связи, источником или предназначены для указанного элемента модели имеют определенную последовательность.Они отображаются в порядке, в котором они были добавлены.Например, это выписка всегда будет создавать дочерние элементы в том же порядке.
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);
Блокирует
Изменения могут быть предотвращены блокировкой.Блокирует может быть задан для отдельных элементах, в секциях и в хранилище.Если любая из этих уровней имеют блокировку, которая предотвращает тип изменения, который требуется сделать, исключение может вызываться при попытке его.Можно обнаружить блокирует ли набор с помощью element.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 () может принимать то a PresentationElement или a ModelElement.Если задать для него a PresentationElementможно также определить положение на схеме целевого объекта в качестве третьего параметра.
Навигация по и обновление схемы
В DSL, элемент модели домена, который представляет понятие например человек или песня, отдельно от элемента фигуры, который представляет которого отображается на схеме.Элемент модели домена хранит важные свойства и связи понятий.Элемент фигуры хранит размер и положение цвет представления объекта на схеме компонентов и структура его части.
Элементы представления
В определении DSL, каждый элемент, который указывается создает класс, производный от одного из следующих стандартных классов.
Тип элемента |
Базовый класс |
---|---|
Доменный класс |
|
Доменная связь |
|
Фигура |
|
Соединитель |
|
Схема |
Элемент схемы обычно представляет элемент модели.Обычно (но не всегда), a NodeShape представляет экземпляр класса и доменного a BinaryLinkShape представляет экземпляр ссылки доменной.PresentationViewsSubject отношение ссылки форма узла или ссылки к элементу модели, который его представляет.
Каждая фигура узла или ссылки принадлежит к одной схемы.Фигура связи 2 бинарная подключения фигур узла.
Фигуры могут иметь фигуры дочерних элементов в 2 наборах.Фигура в NestedChildShapes набор ограничен ограничивающего прямоугольника родительского элемента.Фигура в RelativeChildShapes список может находиться вне или частично вне границ родительского элемента - например, метки или порта.Схема нет RelativeChildShapes и нет Parent.
Перемещаться между фигурами и элементами
Элементы модели домена и связанные элементы фигуры 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
Навигация по схеме
Обычно не желательно перемещаться между фигурами и соединителями на схеме.Лучше навигация по связям в модели, перемещения между фигурами и соединителями только при необходимости работать в представлении схемы.Эти методы связаны соединители к фигурам на каждом конце:
personShape.FromRoleLinkShapes, personShape.ToRoleLinkShapes
connector.FromShape, connector.ToShape
Многие составные фигуры. они состоят из родительской формы и одного или нескольких уровней дочерних элементов.Говорят, что фигуры, расположенные по отношению к другой форме сво дочерние элементы.Если родительская фигура перемещает, дочерние элементы перемещаются вместе с ней.
относительные дочерние элементы может использоваться вне ограничивающего прямоугольника родительской формы.Вложено дочерние элементы появляются только в пределах границ родительского элемента.
Для получения верхний набор фигур на схеме, используйте:
Diagram.NestedChildShapes
Классы предка фигур и соединителей:
-- ShapeElement
----- NodeShape
------- Diagram
------- YourShape
----- LinkShape
------- BinaryLinkShape
--------- YourConnector
Свойства фигур и соединителей
В большинстве случаев не требуется сделать явные изменения к фигурам.При изменении элементов модели "вверх" правила зафиксировать обновление фигур и соединителей.Дополнительные сведения см. в разделе Реагирование на изменения и их распространение.
Однако некоторые явные полезно делать изменения к фигурам в свойствах, которые не зависят от элементов модели.Например, можно изменить эти свойства:
Size - задает высоту и ширину фигуры.
Location - позиция относительно родительского фигуры или схеме
StyleSet - набор ручек и кистей, используемый для рисования формы или соединитель
Hide тип - делает невидимым
Show - делает форму видимой после a Hide()
Создание элемента и его форма
При создании и связывание его элемент в дерево внедрение связей, форма создается автоматически и связанную с ней.Это делается правилам "адресной привязки", выполняемых в конце транзакции.Однако форма будет отображаться в автоматическ-присвоенное расположение и его форму, цвета и другие функции будут иметь значения по умолчанию.Чтобы контролировать, как фигура создана, можно использовать функцию слияния.Сначала нужно добавить элементы, которые нужно добавить в 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.
Можно также задать цвет и других предоставляемых ими свойств соединителей с помощью этого метода.
Использование транзакций
Фигуры соединители и схемы подтипы ModelElement и живите в хранилище.Поэтому необходимо внести изменения в них только в пределах транзакции.Дополнительные сведения см. в разделе Практическое руководство. Обновление модели с помощью транзакций.
Представление документа и данные документа
Хранение секций
При загрузке модели, соответствующие схемы загружается одновременно.Обычно модель загружается в Store.DefaultPartition и содержимое схемы загружается в другой раздел.Обычно содержимое каждого раздела загрузке и сохранении в отдельный файл.
См. также
Ссылки
Основные понятия
Практическое руководство. Обновление модели с помощью транзакций
Интеграция моделей с помощью Visual Studio Modelbus