基于 XML 和状态机的 WinForms 控件设计






4.98/5 (34投票s)
2002年12月2日
4分钟阅读

87350

1296
使用状态机和全面的XML控件描述,可以极大地简化控件处理代码。
引言
提出的WinForms控件具有三个显著特点:
- 它可以包含并操作任何实现特定统一接口的元素;
- 它的主要输出是当前状态;
- 它完全通过XML进行描述和配置。
该控件是一个基于UserControl
的容器,用于存放敏感元素(下文简称元素)。填充各种类型的元素后,它可以作为不同应用程序的可自定义工具栏、工具箱或热点控件。该控件称为Open Group Control (OGC),因为它包含并管理可扩展(开放)的元素组。与普通工具栏相比,这种控件的优势在于它不需要编写用户代码来处理控件的内部元素及其关系。OGC为用户提供可重用的已编译(因此希望已调试)的模块,其中包含一些有用的工具和机制(例如,错误处理)。
元素
控件的元素应遵循特定规则:实现特殊的IElement
接口,并放置在单独的程序集中。如果元素被实例化,则控件会动态加载该元素的程序集。这意味着元素可以是不同类型的(非WinForms控件类型,或基于WinForms控件),并且可以在不更改控件本身的情况下开发新的元素类型。因此,OGC允许通过设计新的元素类型来扩展。目前,已实现了两种元素类型,分别对应以下类:
OGCVisualElement
- 热点元素,用作多状态按钮的图像;
OGCComboBox
- 组合框。
元素类实现在单独的动态加载程序集中。
状态
控件包含一个元素组(集合)。每个元素都有几个不同的状态。元素状态的向量构成了整个控件的状态(控件的状态)。这种关系由控件状态矩阵表示。通过激活一个元素(例如,单击热点元素,在组合框中选择一项),用户使控件从一个状态迁移到另一个状态。每个元素的此类迁移规则都应由元素的“状态迁移矩阵”定义。XML配置文件包含控件的“控件状态矩阵”以及其每个元素的“状态迁移矩阵”。矩阵的结构在文件Additional_Notes.html中有详细解释,该文件可随本文代码示例一起加载。
组成
程序集OGCLib包含基本类型和接口定义:
OGControl
– 元素容器,提供OGC的主要功能,包括鼠标操作、控件的状态机、停靠和错误处理机制,并初始化元素的几何修改。
Configurator
– 负责使用XML文件配置OGC。
ErrorEventArgs
– 此类的对象用作错误处理委托的参数;包含错误严重性和消息。
该程序集包含以下接口的定义:
IElement
– 元素类型的基类。
IFactory
– 元素类型程序集中的元素实例化Factory
类的基类。
程序集 OGCVisualElementLib 和 OGCComboBoxLib 包含相应的基于IElement
的元素类OGCVisualElement
和OGCComboBox
。这些程序集通过OGControl.AddElement()
方法使用反射技术动态加载。
配置
所有控件的配置数据都放在XML文件中。文件OGCErrorMessages.xml包含所有错误消息模板。当前,此文件名是硬编码的,无法更改。从XML读取错误消息模板允许用户配置错误消息并以其母语接收。应用程序中的所有OGC及其元素共享此信息。控件使用Configurator
类从其配置文件中读取与元素相关的数据。基于这些数据,控件加载相应的程序集,并使用程序集的Factory : IFactory
类实例化所请求的元素。
用法
要创建一个功能最少的OGC,父窗体应调用OGC构造函数,并将XML配置文件名称作为参数传递,然后将新实例化的控件添加到其控件列表中。
Controls.Add(new OGControl("Configurator.xml"));
应实现用于处理OGC的StateChangedEvent
和ErrorEvent
静态事件的委托。
delegate void StateChangedEventHandler(OGControl source, EventArgs ea);
delegate void ErrorEventHandler(OGControl source, ErrorEventArgs eea);
应实现。
为了增强功能,可以重写一些虚拟方法,例如OnChangeState()
和ConstructTip()
。
代码示例和附加说明
可供下载。可以使用__RunMe_First_To_Build.bat批处理文件构建示例。批处理文件_Run_Example_1.bat和_Run_Example_2.bat允许运行两个相关示例。文件Additional_Notes.html提供了关于矩阵结构和示例的更全面的解释,而文件Data_to_Examples.txt包含示例的控件状态矩阵。
进一步开发
该控件的当前版本可以通过多种方式进行改进/扩展,例如:在控件中加入设计模式(允许使用鼠标修改大小、更改元素位置并填写配置XML文件来定义其状态),通过标题右键单击浮动菜单添加更多功能(例如,使控件不可见)等。当然,还可以设计更多类型的基于IElement
的元素。
结论
本文介绍了一种WinForms控件设计方法,该方法以状态机、XML配置和基于统一接口的内部元素处理为特征。该控件及其元素类型在很大程度上是自给自足的。在许多情况下,这种结构可以为用户节省开发和调试控件相关代码的时间。
对于建设性的讨论、建议和错误报告,我将非常感激。
谢谢
我非常感谢.S.Rod.在文章组织和标题方面提出的建议。