创建基于 Windows 窗体的域特定语言

可以使用 Windows 窗体显示域特定语言 (DSL) 模型的状态,而不是使用 DSL 关系图。 本主题将逐步完成绑定 Windows 窗体到 DSL,使用 Visual Studio 可视化和 SDK 建模。

DSL 实例显示“Windows 窗体 UI”和模型资源管理器。

DSL-Wpf-2

创建 Windows 窗体 DSL

“最小 WinForm 设计器” DSL 模板创建可以修改以适合您的需求的最小 DSL。

若要创建最小的 WinForms DSL

  1. 创建一个来自**“最小 WinForm 设计器”**模板的 DSL。

    在本演练中假设的名称如下所示:

    解决方案和 DSL 名称

    FarmApp

    命名空间

    Company.FarmApp

  2. 使用模板提供的初始示例的测试:

    1. “转换所有模板”。

    2. 生成并运行示例(“CTRL+F5”)。

    3. 在 Visual Studio 的实验实例中,在调试项目中打开Sample文件。

      注意到在 Windows 窗体控件中显示。

      您还可以查看显示在资源管理器中的模型的元素。

      在窗体或资源管理器中添加元素,并注意它们显示在另一个 display 中。

在 Visual Studio 的主实例中,请注意有关 DSL 解决方案的下列问题:

  • DslDefinition.dsl 中不包含任何关系图元素。 这是因为,不使用 DSL 关系图查看此 DSL 的实例模型。 相反,您将绑定 Windows 窗体到模型,窗体的元素将显示该模型。

  • 除了 Dsl 和 DslPackage 项目外,解决方案包含第三个名为 UI. UI 的项目,项目包含 Windows 窗体控件的定义。 DslPackage 依赖 UI,并且, UI 依赖 Dsl。

  • 在 DslPackage 项目的 UI 项目中定义“Windows 窗体”控件,UI\DocView.cs 包含演示该控件的编码。

  • UI 项目包含绑定到 DSL 的窗体控件的正在运行的示例。 但是,当您更改了 DSL 定义,它将不起作用。 UI 项目包含:

    • 名为 ModelViewControl 的“Windows 窗体”类。

    • 名为 ModelViewControl 的文件包含 DataBinding.cs 其他的部分的定义。 在**“解决方案资源管理器”中查看它的内容,打开文件和选择快捷菜单“查看代码”**。

Dd820642.collapse_all(zh-cn,VS.110).gif有关 UI 项目

当更新 DSL 定义文件以定义您自己的 DSL 时,您必须在 UI 项目中更新控件,以显示您的 DSL。 不同于Dsl 和 DslPackage项目,示例UI项目不是从DslDefinitionl.dsl中生成的。 可以添加 .tt 文件,以生成您所需要的代码(尽管其不是在此演练中转换的)。

正在更新 DSL 定义

以下 DSL 定义用于此演练。

DSL-Wpf-1

更新 DSL 定义

  1. 打开在 DSL 设计器的 DslDefinition.dsl。

  2. 删除 ExampleElement

  3. ExampleModel 域类重命名为 Farm。

    赋予其其他的名为 大小 类型的 Int32,和 IsOrganic 类型的 Boolean的域属性。

    备注

    如果删除根域类然后创建新的根,则必须重新设置编辑器根类属性。在“DSL 资源管理器”中,选择“编辑器”。然后在“属性”窗口设置“根类”为 Farm。

  4. 请使用**“已命名的域类”**工具穿件以下的域类:

    • Field – 给定名为 Size 的附加域属性。

    • Animal 在“属性”窗口中,将**“继承修饰符”设置为“抽象”**。

  5. 使用**“域类”**工具创建以下类:

    • Sheep

    • Goat

  6. 请使用**“继承”**工具使“山羊” 和“绵羊”从“动物”中继承。

  7. 请使用**“嵌入”**工具嵌入“场”下的 “域”和 “动物”。

  8. 建议您整理关系图。 若要减少复制的元素数,请使用叶元素的快捷菜单的**“将子树此处”**命令。

  9. 解决方案资源管理器工具栏中的**“转换所有模板”**。

  10. 生成**“Dsl”**项目。

    备注

    在此阶段,其他项目在生成时会发生错误。但是,我们需要生成 DSL 项目,这样其程序集可用于数据源配置向导。

更新 UI 项目

现在可以创建用于显示在 DSL 模型中存储的信息的新用户控件。 将用户控件与模型相连接的最简单的方法是通过数据绑定。 名为**“ModelingBindingSource”**的数据绑定适配器类型转为 DSL 连接到非 VMSDK 接口设计。

定义您的 DSL 模型作为数据源

  1. 在**“数据”菜单上,选择“显示数据源”**。

    将打开**“数据源”**窗口。

    选择**“添加新数据源”**。 **“数据源配置向导”**打开。

  2. 选择**“对象”“下一步”**。

    展开 DslCompany.FarmApp,然后选择 Farm,它是模型的根类。 选择**“完成”**。

    在“解决方案资源管理器中”,“UI”项目现在包含Properties\DataSources\Farm.datasource

    您的模型类的属性和关系出现在“数据资源”窗口中。

    DslWpf-3

将模型连接到窗体

  1. 在**“UI”**项目中,请删除所有现有的 .cs 文件。

  2. 向**“UI”项目中添加名为 FarmControl 的新“用户控制”**文件。

  3. 在**“数据源”窗口中,在“场”的下拉菜单上,选择“详细信息”**。

    为其他属性保留默认设置。

  4. 在设计视图中打开 FarmControl.cs。

    将 “数据源”窗口中的**“场”**拖到 FarmControl 上。

    控件集显示,每一个集对应一个属性。 关系属性不生成控件。

  5. 删除 farmBindingNavigator。 这在 FarmControl 设计器中还会自动生成,但对此应用程序无用。

  6. 使用工具箱将创建两个DataGridView实例,并将它们命名为AnimalGridView和FieldGridView。

    备注

    可选步骤是将动画和字段从数据源窗口拖动到控件上方。此操作自动创建数据网格和在网格视图和数据源之间的绑定。但是,此绑定不适用于 DSL。因此最好手动创建数据网格和绑定。

  7. 如果工具箱不包含 ModelingBindingSource 工具,添加它。 在**“数据”** 选项卡的快捷菜单上,选择**“选择项”。 在“选择工具箱项”对话框中,从“.NET Framework Tab”选择“.ModelingBindingSource”**。

  8. 使用工具箱将创建两个ModelingBindingSource实例,并将它们命名为AnimalBinding和FieldBinding。

  9. 设置每一个 ModelingBindingSourceDataSource 属性至 farmBindingSource

    设置 DataMember 属性至 AnimalsFields

  10. 设置 AnimalGridView 的 DataSource 属性至 AnimalBinding,并设置 FieldGridView 的属性至 FieldBinding。

  11. 调整“场”控件的布局满足您的喜好。

ModelingBindingSource 是执行特定于 DSL的若干参数的适配器:

  • 它将包装在 VMSDK 存储事务的更新。

    例如,当用户从数据视图栅格中删除行,正则绑定会导致事务异常。

  • 它确保当用户选择行时属性窗口显示相应的模型元素的属性,而不是数据网格行。

数据源和视图之间的连接架构。

DslWpf4

完成绑定到 DSL

  1. 在**“U”**项目的一个独立的代码文件夹中添加以下代码:

    using System.ComponentModel;
    using Microsoft.VisualStudio.Modeling;
    using Microsoft.VisualStudio.Modeling.Design;
    
    namespace Company.FarmApp
    {
      partial class FarmControl
      {
        public IContainer Components { get { return components; } }
    
        /// <summary>Binds the WinForms data source to the DSL model.
        /// </summary>
        /// <param name="nodelRoot">The root element of the model.</param>
        public void DataBind(ModelElement modelRoot)
        {
          WinFormsDataBindingHelper.PreInitializeDataSources(this);
          this.farmBindingSource.DataSource = modelRoot;
          WinFormsDataBindingHelper.InitializeDataSources(this);
        }
      }
    }
    
  2. 在**“DslPackage”项目中,请编辑“DslPackage\DocView.tt”**来更新下面的变量定义:

    string viewControlTypeName = "FarmControl";
    

测试 DSL

该 DSL 解决方案现在可以编译并运行,尽管您稍后可能想要添加进一步改进。

要测试的 DSL。

  1. 生成并运行解决方案。

  2. 在 Visual Studio 的实验实例中,打开**“示例”**文件。

  3. 在**“FarmApp 资源管理器”中,打开在“场”根节点上的快捷菜单,并选择“添加新山羊”**。

    Goat1 出现在 “动物” 视图。

    警告

    必须使用在“场”节点,而不是“动物”节点的快捷菜单。

  4. 选择 **”场“**根节点并观察其属性。

    在窗体视图中,请改变该场的**“名称”“大小”** 。

    在离开窗体中的每个字段时,相应的属性将在“属性”窗口中更改。

增强 DSL

立即提交更新属性

  1. 在 FarmControl.cs 设计视图中,选择简单的字段(如名称、大小或 IsOrganic)。

  2. 在“属性”窗口中,展开**“DataBindings”,再展开“高级”**.。

    在**“格式设置和高级绑定”对话中,在“数据源更新模式”下,选择OnPropertyChanged**。

  3. 生成并运行解决方案。

    验证更改字段的内容时,立刻更改场模型的相应属性。

提供添加按钮

  1. 在 FarmControl.cs 设计视图中,请使用工具箱来创建窗体上的按钮。

    编辑按钮的名称和文本,如 New Sheep。

  2. 在按钮后打开该代码(例如通过双击它)。

    编辑如下:

        private void NewSheepButton_Click(object sender, EventArgs e)
        {
          using (Transaction t = farm.Store.TransactionManager.BeginTransaction("Add sheep"))
          {
            elementOperations.MergeElementGroup(farm,
              new ElementGroup(new Sheep(farm.Partition)));
            t.Commit();
          }
        }
    
        // The following code is shared with other add buttons:
        private ElementOperations operationsCache = null;
        private ElementOperations elementOperations
        {
          get
          {
            if (operationsCache == null)
            {
              operationsCache = new ElementOperations(farm.Store, farm.Partition);
            }
            return operationsCache;
          }
        }
        private Farm farm
        {
          get { return this.farmBindingSource.DataSource as Farm; }
        }
    

    您将还需要插入以下指令:

    using Microsoft.VisualStudio.Modeling;
    
  3. 为“山羊”和“字段”添加类似的按钮。

  4. 生成并运行解决方案。

  5. 验证新按钮添加项。 新项目应出现在 FarmApp “资源管理器”和适当的数据网格视图中。

    您应当能够在数据网格视图中编辑元素的名称。 您可以从所在位置将其删除。

DSL-Wpf-2

Dd820642.collapse_all(zh-cn,VS.110).gif有关要添加到元素的代码

对于新元素按钮,以下替换代码略微简单。

    private void NewSheepButton_Click(object sender, EventArgs e)
    {
      using (Transaction t = farm.Store.TransactionManager.BeginTransaction("Add sheep"))
      {
        farm.Animals.Add(new Sheep(farm.Partition)); ;
        t.Commit();
      }
    }

但是,此代码不为新项设置默认名称。 它不运行您在 DSL 的 “元素合并指令” 可能已定义的任何自定义的合并,因此,它不运行可能已定义的任何自定义合并代码。

因此我们建议您使用 ElementOperations 来创建新元素。 有关更多信息,请参见自定义元素创建和移动

请参见

概念

如何定义域特定语言

可视化和建模 SDK - 域特定语言

其他资源

编写代码以自定义域特定语言