65.9K
CodeProject 正在变化。 阅读更多。
Home

DSL 建模 - 展开或折叠图表形状的所有子项

2015年10月1日

CPOL

2分钟阅读

viewsIcon

7127

展开/折叠您的 DSL 图表元素,使其更易于使用

引言

当您使用 DSL SDK 时,您可以创建一个工具,用它来绘制您的领域,然后通过 T4 模板和代码生成将其转换为代码。但是,图表可能会很快变得杂乱无章,因此拥有展开/折叠实体的功能可以更轻松地找到您要查找的内容并对其进行处理。

背景

创建特定领域语言模型需要 Visual Studio 建模 SDK

1. 为您的形状添加“已显示/已隐藏”属性

当您在 DSL 设计器中创建形状时,它会在 DSL 项目的 GeneratedCode 文件夹中生成一个与该形状对应的类。但是,这个类是自动生成的,因此您添加到其中的任何代码在模型重建时都会丢失。

相反,您需要创建一个不同的文件夹(我使用名称 CustomCode),并在该文件夹中创建一个与自动生成的形状类同名的部分类。

将一个属性添加到这个部分类中,以指示形状的子项是隐藏还是可见。

    public partial class AggregateGeometryShapeBase
    {
        /// <summary>
        /// Are the linked events/projections/queries/commands visible
        /// </summary>
        private bool m_childrenHidden = false;
        public bool ChildrenHidden
        {
            get
            {
                return m_childrenHidden;
            }
            set
            {
                m_childrenHidden = value ;
            }
        }
    }

2. 为您的 DSL 设计器添加上下文菜单

在您的 DSLPackage 项目中,将有一个名为“Commands.vsct”的文件。这是一个 XML 文件,它定义了当您的 DSL 以图形方式设计时,您的包将添加到 Visual Studio 设计器中的菜单(和其他用户界面功能)。

将一个新的命令添加到此文件,以显示/隐藏形状子项

  <Symbols>
    <!-- Copy every menu identifier here  -->
    <GuidSymbol name="guidCustomDiagramMenuCmdSet"
      value="{986DE2DB-3E48-429B-8474-1248E06D8C27}" >
      <IDSymbol name="grpidDiagramMenuGroup" value="0x01001"/>
      <IDSymbol name="cmdidExpandCollapseAggregateContextMenuCommand" value="0x00003"/>
    </GuidSymbol>
  </Symbols>

(显然,请用您自己生成的 GUID 替换它。)

 <Commands package="guidPkg">
    <Groups>
      <Group guid="guidCustomDiagramMenuCmdSet" 
      id="grpidDiagramMenuGroup" priority="0x0100">
        <!-- These symbols are defined in GeneratedVSCT.vsct -->
        <Parent guid="guidCmdSet" id="menuidContext" />
      </Group>
    </Groups>
    <Buttons>
      <!-- Expand or collapse the selected aggregate-->
      <Button guid="guidCustomDiagramMenuCmdSet" 
      id="cmdidExpandCollapseAggregateContextMenuCommand"
        priority="0x0100" type="Button">
        <Parent guid="guidCustomDiagramMenuCmdSet" 
        id="grpidDiagramMenuGroup"/>
        <CommandFlag>DefaultDisabled</CommandFlag>
        <CommandFlag>DefaultInvisible</CommandFlag>
        <CommandFlag>DynamicVisibility</CommandFlag>
        <Strings>
          <ButtonText>Expand/Collapse Aggregate</ButtonText>
        </Strings>
      </Button>  
    </Buttons>
  </Commands>
  <VisibilityConstraints>
    <!-- Ensure that the diagram commands are only loaded for this DSL -->
    <VisibilityItem guid="guidCustomDiagramMenuCmdSet" 
      id="cmdidExpandCollapseAggregateContextMenuCommand"
      context="guidEditor"/>
  </VisibilityConstraints>

此时,您的菜单实际上不会出现 - 您必须创建一段匹配的代码,该代码与从此 XML 文件自动生成的代码具有相同的类名。

    internal partial class CQRSdslCommandSet
    {
        private Guid guidCustomDiagramMenuCmdSet = new Guid("986DE2DB-3E48-429B-8474-1248E06D8C27");
        private int cmdidShowHideModelTipsContextMenuCommand = 0x00001;
        private int cmdidIncrementEventVersionContextMenuCommand = 0x00002;
        private int cmdidExpandCollapseAggregateContextMenuCommand = 0x00003;

        private int cmdidGenerateCQRSModelCode =  0x00011;

        private int cmdidGenerateCQRSModelDocumentation = 0x00021;

        /// <summary>
        /// Get the set of commands for this CQRS/DSL tool
        /// </summary>
        protected override IList<MenuCommand> GetMenuCommands()
        {
            // Get the standard base commands
            global::System.Collections.Generic.IList<global::System.ComponentModel.Design.MenuCommand>
                commands = base.GetMenuCommands();

            // Add custom commands
            global::System.ComponentModel.Design.MenuCommand menuCommand = null;

            // Add handler for "Expand / CollapseAggregate" menu command
            menuCommand = new DynamicStatusMenuCommand(new EventHandler(OnStatusExpandCollapseAggregate),
                new EventHandler(OnMenuExpandCollapseAggregate),
                new CommandID(guidCustomDiagramMenuCmdSet, 
                      cmdidExpandCollapseAggregateContextMenuCommand));
            commands.Add(menuCommand);

            // return the resulting list
            return commands;

        }
   // - - - -8< - - - - - - - -
   }

您会注意到,在创建命令时传递了两个函数 - 一个 OnStatus... 函数,它确定是否显示、隐藏、启用或禁用菜单,以及一个 OnMenu.. 函数,它在单击菜单时执行代码。

在这种情况下,我们希望只有当前选择了我们顶级形状中的一个时,菜单才可用。

        internal virtual void OnStatusExpandCollapseAggregate(object sender, System.EventArgs e)
        {
            global::System.ComponentModel.Design.MenuCommand cmd = sender
                 as global::System.ComponentModel.Design.MenuCommand;
            cmd.Visible = true;
            cmd.Enabled = false;

            if (this.CurrentSelection.OfType<AggregateGeometryShape>().Count() == 1)
            {
                // One and only one "Aggregate" selected so show the Increment version command
                cmd.Enabled = true;
            }
        }

3. 执行显示/隐藏

菜单处理程序将更新图表视图本身,因此其操作必须在 Microsoft.VisualStudio.Modeling.Transaction 内部执行

        internal virtual void OnMenuExpandCollapseAggregate(object sender, global::System.EventArgs e)
        {
            AggregateGeometryShape agg = this.CurrentSelection.OfType<AggregateGeometryShape>()
                .FirstOrDefault();
            if (null != agg)
            {
                agg.ChildrenHidden = !agg.ChildrenHidden;

                Microsoft.VisualStudio.Modeling.Transaction tShowHide = 
                      agg.Store.TransactionManager.BeginTransaction("Show or hide children");
                // Show/hide all the child links and shapes
                foreach (BinaryLinkShape linkedChild in agg.FromRoleLinkShapes.OfType<BinaryLinkShape >() )
                {
                    linkedChild.SetShowHideState(!agg.ChildrenHidden);
                    if (linkedChild.ToShape != null)
                    {
                        linkedChild.ToShape.SetShowHideState(!agg.ChildrenHidden);
                    }
                }      
                tShowHide.Commit();
            }
        }

历史

  • 2015-10-01:初始版本
© . All rights reserved.