Элементы отсека не отображаются на диаграмме DSL - PullRequest
0 голосов
/ 20 сентября 2008

ОК, так что мой DSL значительно продвинулся с тех пор, как несколько дней назад я задал этот вопрос .

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

Я динамически генерирую подпрограммы из модели, созданной DSL, сохраняю эти диаграммы в виде изображений и затем генерирую документ Word с внедренными этими изображениями. Пока все хорошо.

Но там, где мои фигуры имеют отсеки (например, Операции с сервисным контрактом - можете ли вы догадаться, что это такое, пока?), Заголовок отсека отображается, но ни один из элементов .

Если я проверю свой объект формы, у него будет один вложенный дочерний элемент - ElementListCompartment, который, в свою очередь, содержит несколько элементов, которые я ожидаю отобразить. Свойство ElementListCompartment.IsExpanded имеет значение true (и на заголовке отсека имеется небольшой значок «свертывания»), но где, о, где мои элементы?

Форма была добавлена ​​к диаграмме с помощью

parentShape.FixupChildShapes(modelElement);

Так, кто-нибудь может направить меня в мой веселый путь?

Ответы [ 2 ]

2 голосов
/ 01 июля 2009

Я недавно столкнулся с проблемой, с которой столкнулся, и сумел заставить ее работать, вот история.

Задача, которую я выполнял, состояла в том, чтобы загрузить и отобразить модель домена и связанную диаграмму, сгенерированную пакетом DSL ActiveWriter.

Вот как я реализовал требуемую функциональность (все методы ниже принадлежат классу Form1, который я создал, чтобы поиграть):

private Store LoadStore()
{
    var store = new Store();
    store.LoadDomainModels(typeof(CoreDesignSurfaceDomainModel), typeof(ActiveWriterDomainModel));
    return store;
}

private void LoadDiagram(Store store)
{
    using (var tx = store.TransactionManager.BeginTransaction("tx", true))
    {
        var validator = new ValidationController();
        var deserializer = ActiveWriterSerializationHelper.Instance;
        deserializer.LoadModelAndDiagram(store,
            @"..\..\ActiveWriter1.actiw", @"..\..\ActiveWriter1.actiw.diagram", null, validator);
        tx.Commit();
    }
}

private DiagramView CreateDiagramView()
{
    var store = LoadStore();
    LoadDiagram(store);

    using (var tx = store.TransactionManager.BeginTransaction("tx2", true))
    {
        var dir = store.DefaultPartition.ElementDirectory;
        var diag = dir.FindElements<ActiveRecordMapping>().SingleOrDefault();
        var view = new DiagramView(){Diagram = diag};
        diag.Associate(view);
        tx.Commit();

        view.Dock = DockStyle.Fill;
        return view;
    }
}

protected override void OnLoad(EventArgs e)
{
    var view = CreateDiagramView();
    this.Controls.Add(view);
}

Этот материал работал в основном отлично: он корректно загружал диаграмму из файлов, созданных в Visual Studio, рисовал диаграмму в моей пользовательской форме окон, поддерживал прокрутку холста и даже позволял мне перетаскивать фигуры здесь. Однако меня беспокоила одна вещь - отсеки были пусты и имели имя по умолчанию, то есть «Отсек».

Гугл вообще не помог, поэтому мне пришлось копаться самостоятельно. Это было не очень легко, но с помощью Reflector и, потратив пару часов, мне удалось заставить этот сценарий работать, как и ожидалось!

Проблема заключалась в следующем. К моему удивлению, библиотеки DSL неправильно рисуют определенные элементы диаграммы сразу после их добавления на диаграмму. Иногда рисуются только заглушки определенных форм (как показано на первом рисунке). Таким образом, иногда нам нужно вручную попросить библиотеку перерисовать фигуры диаграмм.

Эта функция может быть реализована с помощью так называемых «правил», которые фактически являются обработчиками событий, которые запускаются определенными событиями диаграммы. По сути, нам нужно прикрепить определенный обработчик к событию диаграммы с добавлением элементов и обеспечить инициализацию фигуры.

К счастью, нам даже не нужно писать какой-либо код, так как дизайнер DSL автоматически генерирует и правила исправления, и служебный метод, который присоединяет эти правила к диаграмме (см. Ниже EnableDiagramRules). Все, что нам нужно сделать - это вызвать этот метод сразу после создания хранилища (до загрузки модели и диаграммы).

private Store LoadStore()
{
    var store = new Store();
    store.LoadDomainModels(typeof(CoreDesignSurfaceDomainModel), typeof(ActiveWriterDomainModel));
    ActiveWriterDomainModel.EnableDiagramRules(store);
    return store;
}

/// <summary>
/// Enables rules in this domain model related to diagram fixup for the given store.
/// If diagram data will be loaded into the store, this method should be called first to ensure
/// that the diagram behaves properly.
/// </summary>
public static void EnableDiagramRules(DslModeling::Store store)
{
    if(store == null) throw new global::System.ArgumentNullException("store");

    DslModeling::RuleManager ruleManager = store.RuleManager;
    ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.FixUpDiagram));
    ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.ConnectorRolePlayerChanged));
    ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.CompartmentItemAddRule));
    ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.CompartmentItemDeleteRule));
    ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.CompartmentItemRolePlayerChangeRule));
    ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.CompartmentItemRolePlayerPositionChangeRule));
    ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.CompartmentItemChangeRule));
}

Код выше работает следующим образом:

  1. При добавлении нового элемента на диаграмму (например, во время десериализации диаграммы) срабатывает правило "FixUpDiagram".

  2. Затем правило вызывает Diagram.FixUpDiagram(parentElement, childElement), где childElement обозначает добавляемый элемент, а parentElement обозначает его логического родителя (определяется с помощью хитрой условной логики, поэтому я не пытался воспроизвести его себя).

  3. Вниз по трассировке стека Метод FixUpDiagram вызывает EnsureCompartments методы всех форм классов на диаграмме.

  4. Метод EnsureCompartments перерисовывает отсеки классов, превращая заглушку «[-] Отсек» в полноразмерную форму «Свойства», как показано на рисунке выше.

P.S. Стив, я заметил, что ты назвал исправление, но оно все еще не работало. Ну, я не профессионал в DSL SDK (только начал использовать его пару дней назад), поэтому не могу объяснить, почему у вас могут быть проблемы.

Возможно, вы вызвали исправление с неправильными аргументами. Или, возможно, Diagram.FixupDiagram (parent, newChild) делает что-то не так, как родительский.FixupChildShapes (newChild). Однако вот мой вариант, который просто работает. Надеюсь, это также поможет.

1 голос
/ 29 сентября 2008

Может быть, мой ответ немного запоздал, но подтвердили ли вы с помощью DSL Explorer, что в ваших отделениях есть предметы?

...