Поделиться через


Перемещение по модели и обновление модели в коде программы

Можно написать код для создания и удаления элементов модели, задавать их свойства и создания и удаления связей между элементами.Все изменения необходимо выполнять в рамках транзакции.Если элементы, отображаемые на схеме, то будет исправлена схема "вверх" автоматически в конце транзакции.

Содержание раздела

Определение DSL примера

Перемещение модель

Доступ к данным класса

Выполните изменения в транзакции

Создание элементов модели

Создание отношения связей

Удаление элементов

Удаление отношения связей

Переупорядочение ссылки на связи

Блокирует

Копировать и вставить

Навигация по и обновление схемы

Перемещаться между фигурами и элементами

Свойства фигур и соединителей

DocView и DocData

Фигуры соединители и схемы, и их отношения к элементам модели описаны в отдельном разделе.Дополнительные сведения см. в разделе [перенаправление] Практическое руководство. Перемещение по схеме и ее обновление.

Определение DSL примера

Это основной части DslDefinition.dsl примеры в этом разделе:

Схема определения DSL — модель семейного дерева

Эта модель экземпляр этого DSL:

Модель1 семейного древа Тюдор

Cc512845.collapse_all(ru-ru,VS.110).gifСсылки и пространства имен

Чтобы запустить код в этом разделе, должны ссылаться на:

Microsoft.VisualStudio.Modeling.Sdk.11.0.dll

Код будет использовать это пространство имен:

using Microsoft.VisualStudio.Modeling;

Кроме того, при написании кода в другом проекте из одного, в котором определен данный DSL, нужно импортировать сборку, которая построена проектом Dsl.

Перемещение модель

Cc512845.collapse_all(ru-ru,VS.110).gifСвойства

Свойства домена, указанные в определении DSL становятся свойствами, которые можно открыть в программном коде:

Person henry = ...;

if (henry.BirthDate < 1500) ...

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

Если нужно задать свойство, необходимо сделать in a транзакция.

henry.Name = "Henry VIII";

Если в определении DSL, свойство Тип существует CALCULATEDнельзя задать его.Дополнительные сведения см. в разделе Вычисляемые и пользовательские свойства хранилища.

Cc512845.collapse_all(ru-ru,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(ru-ru,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

  • 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, элемент модели домена, который представляет понятие например человек или песня, отдельно от элемента фигуры, который представляет которого отображается на схеме.Элемент модели домена хранит важные свойства и связи понятий.Элемент фигуры хранит размер и положение цвет представления объекта на схеме компонентов и структура его части.

Cc512845.collapse_all(ru-ru,VS.110).gifЭлементы представления

Схема классов базовых типов фигур и элементов

В определении DSL, каждый элемент, который указывается создает класс, производный от одного из следующих стандартных классов.

Тип элемента

Базовый класс

Доменный класс

ModelElement

Доменная связь

ElementLink

Фигура

NodeShape

Соединитель

BinaryLinkShape

Схема

Diagram

Элемент схемы обычно представляет элемент модели.Обычно (но не всегда), a NodeShape представляет экземпляр класса и доменного a BinaryLinkShape представляет экземпляр ссылки доменной.PresentationViewsSubject отношение ссылки форма узла или ссылки к элементу модели, который его представляет.

Каждая фигура узла или ссылки принадлежит к одной схемы.Фигура связи 2 бинарная подключения фигур узла.

Фигуры могут иметь фигуры дочерних элементов в 2 наборах.Фигура в NestedChildShapes набор ограничен ограничивающего прямоугольника родительского элемента.Фигура в RelativeChildShapes список может находиться вне или частично вне границ родительского элемента - например, метки или порта.Схема нет RelativeChildShapes и нет Parent.

Cc512845.collapse_all(ru-ru,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(ru-ru,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(ru-ru,VS.110).gifСвойства фигур и соединителей

В большинстве случаев не требуется сделать явные изменения к фигурам.При изменении элементов модели "вверх" правила зафиксировать обновление фигур и соединителей.Дополнительные сведения см. в разделе Реагирование на изменения и их распространение.

Однако некоторые явные полезно делать изменения к фигурам в свойствах, которые не зависят от элементов модели.Например, можно изменить эти свойства:

  • Size - задает высоту и ширину фигуры.

  • Location - позиция относительно родительского фигуры или схеме

  • StyleSet - набор ручек и кистей, используемый для рисования формы или соединитель

  • Hide тип - делает невидимым

  • Show - делает форму видимой после a Hide()

Cc512845.collapse_all(ru-ru,VS.110).gifСоздание элемента и его форма

При создании и связывание его элемент в дерево внедрение связей, форма создается автоматически и связанную с ней.Это делается правилам "адресной привязки", выполняемых в конце транзакции.Однако форма будет отображаться в автоматическ-присвоенное расположение и его форму, цвета и другие функции будут иметь значения по умолчанию.Чтобы контролировать, как фигура создана, можно использовать функцию слияния.Сначала нужно добавить элементы, которые нужно добавить в 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(ru-ru,VS.110).gifИспользование транзакций

Фигуры соединители и схемы подтипы ModelElement и живите в хранилище.Поэтому необходимо внести изменения в них только в пределах транзакции.Дополнительные сведения см. в разделе Практическое руководство. Обновление модели с помощью транзакций.

Представление документа и данные документа

Схема классов стандартных типов схем

Хранение секций

При загрузке модели, соответствующие схемы загружается одновременно.Обычно модель загружается в Store.DefaultPartition и содержимое схемы загружается в другой раздел.Обычно содержимое каждого раздела загрузке и сохранении в отдельный файл.

См. также

Ссылки

ModelElement

Основные понятия

Проверка в доменных языках

Практическое руководство. Обновление модели с помощью транзакций

Интеграция моделей с помощью Visual Studio Modelbus

Другие ресурсы

Создание кода из доменного языка

Реагирование на изменения и их распространение