隔室项目未显示在DSL图表中

时间:2020-03-06 14:27:47  来源:igfitidea点击:

好的,自从几天前我问这个问题以来,我的DSL有了长足的进步。

重构代码后,我将立即发布自己的答案,但是现在,我遇到了另一个问题。

我正在根据DSL创建的模型动态生成子图,将这些图另存为图像,然后生成嵌入了这些图像的Word文档。到目前为止,一切都很好。

但是,在我的形状带有隔离专区的位置(例如,我们可以根据服务合同上的操作来猜猜它是什么吗?),隔离专区头会显示,但不会显示任何项目。

如果我检查我的形状对象,则它有一个嵌套的子元素ElementListCompartment,该元素又具有我希望显示的许多项目。 ElementListCompartment.IsExpanded属性设置为true(并且隔离专区标题上有一个小"折叠"图标),但是我的项目在哪里呢?

形状已使用添加到图中

parentShape.FixupChildShapes(modelElement);

那么,有人可以引导我走快乐的道路吗?

解决方案

也许我的回答有点晚了,但是我们是否使用DSL Explorer确认隔间中有物品?

我最近遇到了一个相关的问题,并设法使其起作用,所以这就是故事。

我正在执行的任务是加载并显示由ActiveWriter的DSL软件包生成的域模型和相关图。

这是我实现所需功能的方式(以下所有方法均属于我创建的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创建的文件加载图表,将图表绘制到我的自定义窗口窗体中,支持滚动画布,甚至允许我在此处拖动形状。但是,有一件事是困扰我,这些车厢是空的,并具有默认名称,即"车厢"。

Google根本没有帮助,所以我不得不自己深入研究。并不是很容易,但是在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));
}

上面的代码如下工作:

  • 在将新元素添加到图中之后(例如,在图的反序列化期间),将触发规则" FixUpDiagram"。
  • 然后,该规则调用Diagram.FixUpDiagram(parentElement,childElement),其中childElement代表要添加的元素,parentElement代表其逻辑父元素(使用棘手的条件逻辑确定,因此我没有尝试重现它我自己)。
  • 沿着堆栈跟踪,FixUpDiagram方法调用图中所有类形状的EnsureCompartments方法。
  • sureCompartments方法重新绘制类的隔离专区,将存根" [-]隔离专区"图形转换为成熟的"属性"形状,如上图所示。

P.S.史蒂夫(Steve),我注意到我们确实致电了修正程序,但仍然无法正常进行。好吧,我不是DSL SDK的专业人士(几天前才开始使用它),所以无法解释我们为什么会遇到麻烦。

也许,我们用错误的参数调用了修正程序。也许Diagram.FixupDiagram(parent,newChild)所做的事情与parent.FixupChildShapes(newChild)所做的事情有所不同。但是,这是我的变体,它可以正常工作。希望这也能有所帮助。