Элементы отсека, не отображенные на диаграмме DSL

StackOverflow https://stackoverflow.com/questions/105522

  •  01-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

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

parentShape.FixupChildShapes(modelElement);

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

Это было полезно?

Решение

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

Задача, которую я реализовывал, состояла в том, чтобы загрузить и отобразить модель предметной области и связанную с ней диаграмму, сгенерированную 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, нарисовал диаграмму в моей пользовательской форме Windows, поддержал прокрутку холста и даже позволил мне перетаскивать сюда фигуры.Однако одна вещь не давала мне покоя - отсеки были пусты и имели имя по умолчанию, т.е."Купе".

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

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

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

К счастью, нам даже не нужно писать какой-либо код, поскольку DSL designer автоматически генерирует как правила исправления, так и служебный метод, который привязывает эти правила к схеме (см. 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 перерисовывает ячейки класса, превращая графическую заглушку "[-] Compartment" в полномасштабную форму "Properties", как показано на рисунке, приведенном по ссылке выше.

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

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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top