代码之家  ›  专栏  ›  技术社区  ›  Steve Morgan

DSL图中未显示的隔间项目

  •  0
  • Steve Morgan  · 技术社区  · 16 年前

    好的,自从我问起,我的DSL已经有了很大的进步 this question 几天前。

    我正在从DSL创建的模型动态生成子图,将这些图保存为图像,然后生成嵌入这些图像的Word文档。到目前为止,一切顺利。

    但是,如果我的形状有隔间(例如,服务合同上的操作-您能猜出它是什么吗?),那么隔间标题将显示,但 没有一项

    使用将形状添加到图表中

    parentShape.FixupChildShapes(modelElement);
    

    那么,有谁能指引我快乐的道路吗?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Eugene Burmako    15 年前

    我最近遇到了一个相关的问题,并设法让它发挥作用,所以故事是这样的。

    我执行的任务是加载和显示一个域模型以及由ActiveWriter的DSL包生成的关联图。

    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);
    }
    

    这些东西工作得很好:它正确地从VisualStudio创建的文件中加载了图表,在我的自定义windows窗体中绘制了图表,支持滚动画布,甚至允许我在这里拖动形状。然而,有一件事困扰着我——隔间是空的,有默认名称,即“隔间”。

    谷歌根本帮不上忙,所以我不得不自己动手。这不是很容易,但在Reflector的帮助下,在花了几个小时后,我成功地使这个场景如预期的那样工作!

    幸运的是,我们甚至不需要编写任何代码,因为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. EnsureRecompartments方法重新绘制类的分区,将存根“[-]分区”图形转换为完整的“属性”形状,如上面链接的图片所示。

    也许,你用错误的论点进行了修正。或者可能是Diagram.FixupDiagram(parent,newChild)的功能与parent.FixupChildShapes(newChild)的功能不同。然而,这里是我的变体,它刚刚起作用。希望这也有帮助。

        2
  •  1
  •   Luis Filipe    16 年前