开源纯C#工控 关+组态软件(九)定制Visual Studio

一、   引子

因为最近很忙(lan),很久没发博了。不少朋友对那个右键弹出菜单和连线的功能很感兴趣,因为VS本身是不包含这种功能的。

 大家想这是什么鬼,怎么我的设计器没有,其实这是一个微软黑科技,如果用好,VS可以打造为你专用的神兵利器。

二、   什么是WPF设计器扩展

WPF 设计器基于一个具有可扩展的体系结构的框架,用户可以扩展这种框架以创建自己的自定义设计体验。

通过扩展 WPF 设计器对象模型,可以在很大程度上自定义 WPF 内容的设计时外观和行为。例如,可以通过下列方式扩展 WPF 设计器:

  • 利用增强的图形自定义移动并调整标志符 的大小。

  • 向设计图面添加一个标志符 ,在鼠标移动时该标志符 可以使所选控件倾斜。

  • 在不同工具之间修改控件的设计时外观和行为。

  • WPF 设计器 体系结构支持 WPF 的所有表现力。这样便可以创建很多以前不可能拥有的可视化设计体验。

三、   如何实现设计器扩展

  • API总体架构

 

VS的状态分为设计时和运行时。设计时就是你打开VS,拖拽控件,界面布局,属性设置,代码编写,打交道的对象是Visual Studio;运行时就是你编译运行自己的exe文件。

  • 如何实现

要实现一个完整的设计器扩展,要经历以下过程:

定义元数据,设计器需要知道哪些控件具有哪些扩展。这是通过Metadata 类来实现的:Metadata 类有一个AttributeTable方法,在其中构建了控件和功能(即相应的Provider)的映射关系。

using Microsoft.Windows.Design.Features;

using Microsoft.Windows.Design.Metadata;

 

 

[assembly: ProvideMetadata(typeof(HMIControl.VisualStudio.Design.Metadata))]

namespace HMIControl.VisualStudio.Design

{

    internal class Metadata : IProvideAttributeTable

    {

        // Accessed by the designer to register any design-time metadata.

        public AttributeTable AttributeTable

        {

            get

            {

                AttributeTableBuilder builder = new AttributeTableBuilder();

                //InitializeAttributes(builder);

                // Add the adorner provider to the design-time metadata.

                builder.AddCustomAttributes(

                    typeof(LinkableControl),

                    new FeatureAttribute(typeof(ControlAdornerProvider))

                    //new FeatureAttribute(typeof(TagComplexContextMenuProvider))

                    );

                builder.AddCustomAttributes(

                  typeof(HMIControlBase),

                  //new FeatureAttribute(typeof(LinkLineAdornerProvider)),

                  new FeatureAttribute(typeof(TagComplexContextMenuProvider)));

                builder.AddCustomAttributes(

                    typeof(LinkLine),

                    new FeatureAttribute(typeof(LinkLineAdornerProvider)),

                    new FeatureAttribute(typeof(TagComplexContextMenuProvider)));

                builder.AddCustomAttributes(

                    typeof(ButtonBase),

                    new FeatureAttribute(typeof(TagWriterContextMenuProvider)));

                builder.AddCustomAttributes(

                  typeof(HMIButton),

                  new FeatureAttribute(typeof(TagWindowContextMenuProvider)),

                  new FeatureAttribute(typeof(TagComplexContextMenuProvider)),

                  new FeatureAttribute(typeof(TagWriterContextMenuProvider)));

                builder.AddCustomAttributes(

                  typeof(FromTo),

                  new FeatureAttribute(typeof(TagWindowContextMenuProvider)));

                return builder.CreateTable();

            }

        }

    }

}

定义具体的Provider,所有的Provider都执行如下次序:根据用户选择,找到相关控件,并进行操作,将操作结果反馈给设计器。

根据设计器扩展的默认规则,在正确的位置使用正确的命名方式,否则你的扩展不会出现在设计器。这些默认规则包括:

命名空间规则:将设计器扩展项目的命名空间设置为HMIControl.VisualStudio.Design(HMIControl即控件库的命名空间),以便设计器能够发现元数据。

项目路径规则:将项目的输出路径设置为“..HMIControlbin”(HMIControl即控件库的项目路径)。 使控件的程序集与元数据程序集位于同一文件夹中,从而可为设计器启用元数据发现。

  • 如何调试

一段不能加断点调试的代码会给编写者带来很大困扰。但设计器扩展有一个特殊性:没法在运行时加断点。好在微软早就为我们安排好了一切。具体可参考https://msdn.microsoft.com/zh-cn/sqlserver/bb514636

即调试时需要更改项目的属性,设置启动程序为VS的可执行文件: devenv.exe.相当于再打开一个新的VS作为运行时。调试时打开你的设计器操作,会发现第一个打开的VS中已经命中断点了。

 

 

四、   组态定制需求的实现

  • 界面连线的实现

设计目标:实现两个HMI控件的连线。每个控件最多有上下左右四个位置(即锚点,也可以少于四个甚至没有),连线从A控件任一位置引出,自动寻找路径,连到B控件的任一位置;路径不能穿越其他控件,而应自动绕开。连线均为直线,不能为圆弧线或斜线;在控件位置改变时,连线重新计算并绘制。

设计过程:具有锚点的控件均继承LinkableControl类。锚点装饰器类为ControlAdorner,是一个控件容器,包含上下左右四个锚点,每个锚点由PinAdorner 定义,包含锚点的外形、自动生成路径等功能。路径发现由PathFinder类实现。与设计器交互通过继承AdornerProvider 类实现。

运行过程:通过AdornerProvider 类的Activate事件,获取当前点击(激活)的控件并转换为LinkableControl,并找到控件的父容器Panel、控件的装饰器ControlAdorner及其包含的每个PinAdorner、设计器包装DesignerView。在每个PinAdorner的鼠标点击和拖放事件内,可探索到其他控件的锚点、规划路径、生成连线LinkLine。

同时要考虑设计器进行缩放时路径的变化,在DesignerView的ZoomLevelChanged事件中处理。

  • 右键菜单的实现

设计过程:TagComplexContextMenuProvider 继承了ContextMenuProvider,如果菜单“ComplexEditor”被激活,触发Exeute事件,则弹出窗体TagComplexEditor,以设置控件的动画关联的变量表达式;操作结果将写回控件的TagReadText 属性。

  • 未来改进

相关文章: 

  • .NET十年回顾

  • 开源纯C#工控 关+组态软件

  • 开源纯C#工控 关+组态软件(三)加入一个新驱动:西门子S7

  • 开源纯C#工控 关+组态软件(四)上下位机通讯原理

  • 开源纯C#工控 关+组态软件(五)从 关到人机界面

  • 开源纯C#工控 关+组态软件(六)图元组件

  • 开源纯C#工控 关+组态软件(七)数据采集与归档

  • 开源纯C#工控 关+组态软件(八)表达式编译器

    github地址:https://github.com/GavinYellow/SharpSCADA。QQ群:102486275

    原文地址:http://www.cnblogs.com/evilcat/p/8859223.html


    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

    上一篇 2018年3月16日
    下一篇 2018年3月16日

    相关推荐