动态控件技术

2024-10-16

动态控件技术(精选7篇)

动态控件技术 篇1

在日常的生活中, 我们经常需要对数据进行统计分析, 除了直接显示数字值, 人们还喜欢借助图表来形象的显示数据本身和数据之间的关联关系。大多数情况下我们采用Excel电子表格来处理数据, 它里面提供了丰富的图表工具, 可以生成不同类型的图表, 如柱形图、圆饼图、雷达图等。随着Internet和Web技术的迅速发展, 很多应用和信息数据都通过网络这一载体进行运用, 但之前由于缺乏有效的动态图表生成技术支持, ASP.NET的Web系统中在涉及需要图表技术的地方, 只能采用静态的非动态的图表技术来实现。随着微软推出的Chart控件, 使得这一问题得以解决。该文主要研究Microsoft Chart控件技术在ASP.NET的Web系统中实现动态图表的方法

1 Chart控件

1.1 Chart控件简介

Chart是Microsoft公司基于.NET3.5框架开发的, 用于在Web系统中绘制各种动态图表的控件, 既能与各种不同的数据源高度集成, 所绘制的图表也有漂亮的外观和高度的灵活性, 满足用户的需求。

1.2 Chart控件的类结构

Chart控件的功能非常完整和强大。其类的组成架构分为属性、方法和事件三个部分, 每个部分内又按照需要细分为各种组成模块。表1、表2和表3分别是控件的属性、方法和事件的内部分类。

2 动态图表结构

动态图表的结构主要有图表名称、图例、坐标轴标题、绘图区、图表区、主要网格线、次要网格线、主要刻度值、次要刻度值和值标签等。

3 Web图表的实现

3.1 控件程序集的引入

在ASP.NET的Web项目中使用Chart控件, 首先需要在Web.config文件的配置节的子节里面引入, 这样项目在编译的时候可以找到引用的控件程序集。如果只有很少的网页需要使用Chart控件, 那么直接从工具箱的Data标签中将Chart控件施放到网页上就可以了。

3.2 数据源的绑定

动态图表显示的内容来源于数据, 因此控件如何从数据源获取数据是关键的一步。为了能适应不同类型的数据源, Chart控件被设计为可以通过三种方法与数据源绑定。

第一种方法:使用Data Source属性进行绑定。先通过SQL调用从数据源中获得数据放入数据适配器中, 再将其填充到ADO.NET中的Sql Command对象, 再将此对象赋给Chart控件的Data Source, 实现数据到Chart控件的绑定。

第二种方法:用进行数据绑定。针对动态设置图表数据源的第二种方式, 就是将某一个数据源控件 (例如ta Source或Object Data Source控件) 的ID值指派给Chart控件的Data Source ID。

第三种方法:通过IEnumerable接口进行数据绑定。使用Chart的Data Bind Table方法控件绑定到一个实现IEnumerable接口的对象, 它会根据数据源中的字段自动创建数据系列, 每个字段的数据都会成为一个数据系列, 并添加到Chart控件中。

3.3 数据的导出

Chart控件中的Data Manipulator.Export Series Values方法能将图表的所有数据系列数据全部导出到Data Set对象中, 数据中的每一个系列都会成为Data Set对象中的一个数据表, 数据坐标的X值与Y值会在数据表中成为字段, 字段名称就是X与Y。如果数据系列拥有多个Y值, 这些Y值也都会在数据表中各自成为一个字段额, 字段名称则是Y, Y2, Y3…..以此类推。同样,

如果拥有多个X值, 也会在数据表中各自成为一个字段。

上面图表中每个部门分别有三个数据系列, 在导出之后, 以X和Y值分别形成三个独立的数据表。

3.4 数据系列的处理

数据系列处理首先是分割、合并和复制三种操作。分割是指让一个数据系类成为多个数据系列, 即从单一来源数据系列复制多个Y值到多个目标数据系列。合并是从多个来源数据系列中将值复制到单一目标数据系列中, 是分割数据系列的反方向操作。复制则指其他所有的复制数据系列操作。

不论分割、合并还是复制数据系列, 都是通过Chart.Data Manipulator.Copy Series Values方法来完成。在这些操作之后, 都会产生新的数据系列, 如果要删除原有的数据系列, 必须自行将其删除。

图3中原本只有一个数据系列, 因此只显示柱状动态图。图4中将数据系列复制为两份, 一份显示原先的柱状图, 另外一份数据系列用来显示饼图。

数据系列处理的另一种主要操作是检索操作, 此操作允许用户在表格中点击某一数据, 该数据行在图表中所对应的数据点便会搜索出来, 并且外观也会改变, 以便让用户更容易在图表中识别。

实现原理:获取用户在控件中所选择数据行的主键, 如上图中的数据行主键员工编号, 然后利用方法在数据系列中搜索, 最后在图表区内修改搜索到的数据点外观 (图中将柱状图的背景色改为红色) 以便识别。

3.5 交互式图表实现

网页上的图表只是一个图片, 不具备和用户的交互性, 而Chart控件却能通过事件触发机制实现图表和用户之间的交互。图6和图7演示了如何根据用户点击的区域, 动态的将所点区域的数据饼图从图中分离出来的过程, 功能实现的描述如下:

首先根据数据值, 定义出特定形状的作用点区域。当页面捕捉到用户的单击行为之后, 取得被单击的作用点坐标值, 再根据事先所设定的特定形状的作用点区域, 判断是哪一个点被单击, 并将这个点的Post Back Value值, 传递给Click事件处理程序中的自变量对象类型Image Map Event Args的Post Back Value属性, 引发页面回发并执行Click事件处理程序, 响应用户请求, 将对应的数据扇形区移出。

图6中动态数据饼图的页面初次加载, 默认将用户周一的数据饼块移出。图7中, 在点击用户张五的数据饼块后, 程序获取所属作用点区域, 交付Click程序处理, 将对应的数据饼块移出。

4 结束语

本文探讨了如何在Web系统中运用微软公司的chart控件绑定图表的数据源、导出图表数据、处理数据系列以及绘制各类柱形图、圆饼图、雷达图等图表技术。为ASP.NET的Web系统中图形信息的显示统计和分析提供了一种良好的解决方案。

摘要:微软公司基于.NET平台所开发的用于绘制动态图表的chart控件, 具有功能强大, 美观实用的特点。该文探讨了如何在Web系统中运用这一控件绑定图表的数据源、导出图表数据、处理数据系列以及绘制各类柱形图、圆饼图、雷达图等图表技术, 为ASP.NET的Web系统中图形信息的显示、统计和分析提供了一种良好的解决方案。

关键词:Chart,Web动态图表,ASP.NET,数据源,交互式图表

参考文献

[1]张成才.基于OWC的动态统计图表的设计与实现[J].计算机技术与发展, 2009 (10) .

[2]王永会.一种WebMI S中的统计图形动态生成方法[J].微计算机应用, 2008 (1) .

[3]林永兴.一种基于OWC在Web页动态绘制图表的方法[J].计算机与现代化, 2010 (1) .

[4]杜利峰.基于.NET的企业统计图表的动态绘制方法研究[J].信息技术, 2012 (4) .

[5]丁剑博.OWC系列控件的图形化开发与应用[J].微计算机时代, 2011 (1) .

动态控件技术 篇2

关键词:XML,TabControl,TabPages,控件

在实际程序开发项目中,如何不修改源代码即可满足用户的使用要求变化是每个程序开发人员奋斗的目标。从实际开发的角度看待此问题:用户需求变化可能涉及到整个体系的变化、数据库结构的变化和窗体交互形式的变化,不修改源代码来满足各种变化在实际开发中是不现实的也是不可行的。因此开发过程中最少代码修改是系统分析人员和代码编写人员要考虑的,这直接反映程序投入实际应用中的灵活性和适应性,是衡量一个系统运行好坏的重要依据。任何一个系统都离不开数据的录入和显示,数据信息收集在应用程序的各个功能中都可能涉及到,它是系统最基础的部分。如果能开发一个通用模块,建立录入信息的配置文件,在窗体中动态创建各种控件来代替固定模式输入,势必会极大地提高应用程序灵活性和适应性。这样程序投入实际运行后,可实时地根据客户要求修改录入信息的配置文件,在窗体中动态创建交互控件,灵活地接收和显示用户录入信息,在不修改程序源代码情况下,最大限度提高程序适应性。本文以C#.Net开发代码为例说明。

1 实现原理分析

1.1 结构示意图

动态创建控件技术的实现原理如图1所示。

1.2 控件配置文件(XML)组成

XML是Extensible Markup Language的缩写,即可扩展标记语言是一种可以用来创建自己的标记的标记语言。是一门既无标签集也无语法的新一代标记语言,XML是被设计用来描述数据的,重点是:什么是数据,如何存放数据。利用XML的数据存储特性,将控件相关信息存储在XML格式的文件中,方便数据维护。

图1中的功能模块是应用程序实现的各个功能项。

配置文件XML文件1的功能:记录每个需要录入数据的模块和交互界面中可能需要的TabPages页,由于在创建控件的窗体中不能确定生成交互控件的数量,因此将控件根据需要放置在不同的TabPages页中,TabPages页作为生成控件的父容器。

例如,表1所示的程序模块构成,其数据结构可用XML文件表示为:

“提示信息”是要创建交互控件的提示信息,是Label类的控件。“控件名称”是要创建控件在窗体中的唯一标识。“控件类型”是创建控件的类型,如TextBox、ComBoBox、RadioButton等Visual C#下的各种控件。“控件格式”是特定类型控件的呈现形式,如TextBox控件有单行输入和多行输入形式。“控件值”是创建控件的默认值,对于ComBoBox、RadioButton和ListBox类的控件值,可用分号“;”将不同值分开绑定到控件中,如果控件需从数据库中绑定数据也可在此处指明数据的表名称。“所属页”是配置文件XML文件2中的值。

2 设计说明

2.1 控件呈现

程序运行某功能模块时,首先根据模块的编号,从配置文件1中获取要创建的TabPages信息,建立字符型数组page保存TabPages的显示名称。通过循环在控件呈现窗体的tabControl中添加TabPage页,代码如下:

从配置文件2中获取要创建的交互控件的信息,建立字符型数组prompt、control、inpage、controltype、controlformat、controlvalue分别保存控件的提示信息、控件的ID、控件所属的TabPages、控件类型、控件格式和控件值,这些数组的维数相同,存储顺序分别对应一个控件的各种属性。通过循环从上述数组中获取信息建立各种控件,如:

1)提示信息创建:

2)交互控件创建:

注意:生成的控件一定要指明该控件的Parent属性,即控件的父控件信息,否则会引发错误。控件的坐标位置可根据实际需要编写,此处省略。

2.2 控件输入信息的保存

根据2.1中保存控件信息数组的维数,建立字符型数组values,通过循环保存对应控件的输入值,循环次数是values的个数,即某个功能模块需要的交互控件的总数量。对于某控件要根据该控件的父容器TabPages循环遍历找到控件的值。代码如下:

3 结论

在软件项目开发中,为需要交互数据的功能模块建立控件信息配置文件,编写通用的控件生成和数据获取函数,可大大减少代码编写工作量,使程序代码结构清晰、思路简洁和便于维护。如果交互信息发生变化,则只需对配置文件进行简单的管理维护(如增加、删除控件信息或根据交互内容修改控件的格式等),无须修改程序源代码,即可满足变化的要求,做到以不变应万变,提高程序的适应性。

参考文献

[1]周绪,韦文斌.SQL Server应用与提高[M].北京:清华大学出版社,2000.

[2]桂思强.ASP.net与数据库程序设计[M].北京:中国铁道出版社,2002.

[3]郝刚,袁勇刚.ASP.NET服务器控件开发技术与实例[M].北京:人民邮电出版社,2005.

[4]微软公司.ASP.NET安全应用程序开发[M].北京:清华大学出版社,2003.

基于容器对象的动态控件数组研究 篇3

动态数组[1]可以在运行期间改变数组大小,具有很强的灵活性,为开发者带来极大便利,广泛应用于各个领域[2,3]。动态控件数组就是一种特殊的动态数组,它的元素类型是控件类型。控件数组应该包含以下三个要素:

(1) 允许多个控件共享同一个事件句柄。即动态生成的多个同类型控件可以使用相同的事件名。这一点是BCB已经具备的功能。

(2) 可以在运行期间添加或者删除控件。BCB已经提供了这种机制。

(3) 可以方便地将多个控件组合为控件数组进行管理和使用。要组合控件最好的方法就是使用容器。BCB中能够实现控件数组的容器可以分为三种:第一种是VCL(Visual Componet Library,可视化组件库)中的TList类;第二种是VCL中的DynamicArray类;第三种是STL[4](Standard Template Library,标准模板库)中的Vector容器类。

文献[5]提出一种基于TList类的控件数组实现方法,在其基础上本文提出基于容器类的动态控件数组实现方案,并详细分析了其性能效率。

1 基于TList类的控件数组

1.1 VCL中的TList类

TList是VCL提供的一个用于维护对象列表的类,它是以链式存储指针的方式实现的。它存储了用于维护各种类指针的索引,这些索引存有指向各种对象的指针。为方便在对象列表中添加、删除、查找、访问、排序或者重组对象,TList提供了方便全面的链表功能,包括Capacity,Count,Items等主要属性和Add,Insert,Delete,Clear,First,Last等主要方法,各属性和方法详细信息如表1所示。

1.2 基于TList类的控件数组的实现思想

文献[5]提出一种基于TList类的控件数组实现方案,下面简要阐述其基本思想。

定义TList类型指针对象,建立控件数组CList,并调用构造函数对其进行初始化:

TList *CList = new TList() ;

动态生成控件对象Button,添加到CList中:

为Button声明并自定义事件MBClick,让所有动态生成的控件共享事件句柄:

通过TList对象的Items属性访问CList中的对象,甚至可以在自定义事件中访问TList对象中动态生成的控件:

删除CList中指定成员对象(第i个)时,先将CList中该成员对象的类指针索引装入临时指针,然后删除临时指针所指对象,同时删除控件数组中的指针记录:

清空整个CList时,先删除其中所有成员对象,再用Clear方法清空。程序结束时CList需要销毁,可在窗体的析构函数中加入以下代码:

2 基于DynamicArray模板的控件数组

2.1 VCL中的DynamicArray模板类

DynamicArray是VCL提供的一个用于实现变长动态数组的模板类[6],使用二进制数据块兼容Object Pascal动态数组实现。DynamicArray也可以看作是一个可以存放各种控件对象的容器,只需将动态数组声明中的数据类型设置为相应控件类型即可。为方便管理动态数组,DynamicArray模板提供了Length,High,Low等属性和Copy,CopyRange等方法,并重载了赋值运算符“=”、比较运算符“==”和访问数组元素的“[]”运算符,如表2所示。

2.2 基于DynamicArray模板的控件数组实现思想

利用DynamicArray模板实现动态控件数组时,需要将动态数组的类型设置为某一控件类型,通过在程序中动态修改动态数组的Length属性来实现数组大小的动态变化。下面以动态按钮数组(BArray)为例,详细说明动态控件数组实现思想。

声明动态按钮数组:

DynamicArray BArray ;

动态地向BArray中添加成员对象时,先将BArray的Length属性增加1,以便为待添加的新对象预留空间:

BArray.Length = BArray.Length + 1 ;

创建待添加的控件对象并装入新开辟的空间:

BArray[BArray.High] = (new TButton(this)) ;

获取新添加的控件对象:

TButton* Button = BArray[BArray.High] ;

删除指定成员(比如第i个)对象时,先删除动态数组中第i个成员对象:

delete BArray[i] ;

然后使用循环语句将被删除成员对象后面的元素全部前移:

最后将BArray的Length属性减少1:

BArray.Length = BArray.Length - 1 ;

如果要清空动态数组BArray中的所有成员,先要使用循环语句逐一删除BArray中的所有元素:

然后将动态数组BArray的Length属性设置为0,但无需使用delete语句销毁BArray:

BArray.Length = 0 ;

3 基于Vector容器类的控件数组

3.1 STL中的Vector容器类

Vector是STL容器类中最简单的容器类,通常也是效率最高的容器类。Vector[7]是一个随机存取的Sequence容器,采用连续的内存空间存放数据。它支持常数时间的尾部插入和删除、线性时间的其他位置的插入和删除。Vector模板类class vector接口成员(public)如表3所示。

3.2 基于Vector容器类的控件数组的实现思想

基于Vector容器实现动态控件数组的思想[8],将Vector中元素类型设置为相应的控件类型,然后利用Vector提供的push_back或insert方法,将动态生成的控件对象装入容器中,利用Vector提供的访问容器中元素的方法访问成员对象,或者利用Vector提供的pop_back或erase方法删除容器中的元素。下面还是以动态按钮数组(BVec)为例,详细说明基于Vector的动态控件数组实现过程。

定义相应类型(比如TButton)的Vector容器:

vector BVec ;

创建Button控件对象,然后添加到容器中:

BVec.push_back(new TButton(this)) ;

获取刚加入的控件对象指针,方便后续访问:

TButton* Button = *(BVec.end() - 1) ;

在删除容器中指定的元素(比如第i个元素)时,先要删除容器中该成员对象的类指针所指的对象,然后清除容器中该成员对象的值:

清空容器时先删除容器中所有成员的类指针所指的对象,这一点可以通过定义一个迭代器并遍历容器所有元素来实现。然后再清除容器中所有元素的值:

4 基于容器对象的动态控件数组性能分析

4.1 基于TList类的控件数组性能分析

基于TList类的控件数组应用广泛[9,10],实现方法简单,添加或删除对象方便而高效。但是这种方法存在以下4个方面的缺陷。

安全性问题

TList类本身就是一个缺乏类型安全支持的类。从其Add方法原型int_fastcall Add(void * Item)可以看出,TList对象存储并维护的是void*空指针。但是BCB编译器会将Add函数接收到的任何类型的指针转换为void*类型,而不做任何类型检查。同时,在引用控件数组中的一个对象时,需要将一个void*类型的指针强制转换为相应控件类型的指针。如果控件数组包含多种类型的成员控件,这时就无法确定空指针该强制转换为哪种类型的指针。一旦类型转换错误,那么在访问成员控件时就会产生严重的问题。

内存空间释放问题

一方面,TList不能自动删除列表中的指针;另一方面,由于列表中的指针是空指针,删除空指针的时候不会调用析构器中的析构函数,那么就无法释放内存空间,从而造成内存泄露。

效率问题

实验表明,当TList存储5 000个以上对象时,效率就会大幅下降。

移植性问题

由于BCB的VCL完全是用Object Pascal语言编的,使得BCB同时获得了Pascal和C++的强大功能,同时可移植性就很差。

4.2 基于DynamicArray类的控件数组性能分析

用DynamicArray实现控件数组,原理简单、代码简洁,不存在类型安全和内存释放问题。但是,DynamicArray使用二进制数据块兼容Object Pascal动态数组实现,这会带来系统瓶颈,严重影响运行效率。DynamicArray的空间扩充机制也不尽完美。当数组长度超过固定大小时,就会频繁地重新申请内存空间,并将原来内存空间中的二进制数据块拷贝到新申请的内存空间中,然后将原空间释放掉,这就会大大降低运行效率。特别是如果二进制数据块比较大的时候,系统瓶颈尤其突出。另外,由于DynamicArray是VCL中的模板类,故移植性较差。

4.3 基于Vector容器类的控件数组性能分析

Vector采用线性连续的内存空间存放数据,因而随机访问数组元素和Vector尾部插入元素效率很高,但是在任意位置插入元素的效率比较低。为了提高效率,Vector使用了自增长机制,实际上就是运用动态弹性内存空间[8],随着新元素的加入,自行扩充内存空间。为了合理控制空间大小、提高重新配置空间时的效率,Vector 实际配置的空间比需求空间大一些,以备将来可能的扩充。向Vector中插入元素时,首先考虑备用空间是否足够,如果够就插入到备用空间,否则,重新配置双倍于现在容量的内存空间,然后将原来的数据拷贝到新空间中,最后释放原内存空间。在控件数组中元素个数不超过1 000万个时,Vector的空间扩充方式效率都是很高的。Vector的空间扩充过程如图1所示。

另外,当容器内元素操作比较复杂时,Vector效率不佳。

5 结 语

BCB是一个优秀的应用程序开发平台,其提供的VCL库更是为开发者带来了极大便利。VCL提供的TList和DynamicArray都可以很容易地实现动态控件数组。但是,TList缺乏类型安全支持,而且Dynamic-Array也存在系统瓶颈问题,而且移植性都比较差,因此它们适合于小规模的局部应用的动态控件数组中。而标准模板库STL提供的容器类Vector具有完备的类型安全机制,移植性比较好,执行效率也相对很高,但是在支持数组元素复杂操作方面欠佳,故这种方法适合于较大规模的通用动态控件数组中。总之,没有哪种方法一定是最好的,具体采用什么方法要根据问题规模、应用范围等因素来决定。

参考文献

[1]陈凤祥,李汪根.C++动态数组的实现与重用[J].计算机技术与发展,2010,20(2):79-82.

[2]孙桂娟,张庆明,郑全平,等.基于可变数组管理方法的震塌破坏数值仿真[J].北京理工大学学报,2009,29(6):492-496.

[3]乔平安.动态统计图控件的设计与实现[J].现代电子技术,2006,29(6):118-120.

[4]葛建芳.C++标准模板库与代码重用[J].南通大学学报:自然科学版,2006,5(2):71-74.

[5]许天然.在C++Builder中实现控件数组[J].琼州大学学报,2006,13(5):27-29.

[6]周熙,汪红.C++Builder环境下MVC框架结构的应用[J].中南民族大学学报:自然科学版,2007,26(2):87-89.

[7]宫护震,史云鹏,孙吉赟.一种基于STL(标准模板库)的三维数据可视化容器设计[J].现代电子技术,2007,30(22):80-81.

[8]帖军,王小荣,金佳.移动实时环境下的数据一致性研究[J].中南民族大学学报:自然科学版,2011,30(2):92-95..

[9]景春国,舒冬梅.TList对象在监控软件数据点的内存管理和处理方面的应用[J].现代电子技术,2003,26(2):7-12.

动态控件技术 篇4

TreeView控件能直观展示信息的层次关系及不同层次节点间的一对多的关系, 在Web开发中被普遍应用。RadTreeView控件是保加利亚的Telerik公司开发的RadControls开发工具集中的一个控件, 该系列控件因其用户界面简洁美观, 交互性好, 在全球被广泛使用。为此, 选择RadTreeView作为TreeView控件的典型代表进行动态生成技术的探讨。

2 解决思路

TreeView控件为典型的树形结构实现, 对其相关的讨论即是对树形结构的讨论, 下面仅对树的存储结构进行说明。

2.1 存储结构

为了把各结点之间存在的关系反映在存储结构中, 采用简化的带逆存储结构, 即结点中不存储其子结点的位置信息, 只存储父结点的位置信息及结点本身的信息, 具体含义如图1所示。一个结点由Data (结点的数据, 具有唯一性, 对应RadTreeNode的Value属性) 、Name (结点名称或描述, 对应RadTreeNode的Text属性) 、Level (结点所在的层次, 对应RadTreeNode的Level属性, 第一层为0, 后面层次依次为1、2、3…) 、Parent (父结点的数据Data, 用于关联其父结点, 父结点为根结点的标识为0) 4个属性组成。Data属性的唯一性可以保证其作为父结点的唯一性, 同时保证在精确匹配条件下查找结果的唯一性。

2.2 遍历算法

按广度优先作层次次序遍历, 即从0层开始, 自上而下从左至右逐层访问树的各层上的结点, 直到访问完最下一层的所有结点。

既然在结点的结构中保存了其层次Level属性, 那就能确知树的最大层数 (即最后一层) , 实现过程就无须采用传统的递归方式, 而采取如图2所示的两层嵌套循环模式进行实现:第1层循环控制所要生成的层数i (i=0, 1, 2…) , 第2层循环具体实现第i层所有结点 (j个) 的生成。

3 通用生成代码

以下方法封装在命名空间GeRadTreeView.Comm中, 可直接应用于自己的软件作品中。源代码文件为RadTreeView项目中的RadTreeView.cs。

3.1 遍历

TreeItemList (RadTreeView, DataTable, string, string, string, string, string) 方法:

3.2 更新节点

TreeItemInsert (RadTreeView, string, string, string, string) 方法:

3.3 更新节点

TreeItemInsert (RadTreeView, RadTreeNode, string, string, string) 方法:

4 业务逻辑代码

4.1 取全部结点数据集合

GetInfoClasses () 方法:

4.2取指定结点详细数据

GetInfoClass (int) 方法:

4.3删除指定结点数据

DeleteInfoClass (int) 方法:

4.4更新指定结点数据

UpdateInfoClass (int, DataRow) 方法:

以上方法封装在命名空间GeRadTreeView.BLL.Data中, 源代码文件为BLL项目中的InfoClassManage.cs。表1列出了示例所用数据库表列名与命名空间GeRadTreeView.Comm中Common类的方法参数、RadTreeView节点 (RadTreeNode) 属性三者间的对应关系, 以方便理解。

5源代码

后台代码:

本示例在Windows XP Profession SP3、SQL Server 2000及2005、Microsoft Visual Studio 2008下通过。

6 结语

动态控件技术 篇5

开发环境:VS2008 C#, Access, DevExpress控件包V9.1.4。

示例软件运行环境:.NetFramework2.0, Windows XP/2003/7。

1 问题分析

通常, 使用XtraLayout控件, 需要做以下的几个步骤来实现:

(1) 在窗体上拖拉一个LayoutControl控件, 设置它的填充属性。

(2) 拖拉一些常规编辑控件到LayoutControl中去, 这个时候会发现LayoutControl中除了增加了拖拉的常规编辑控件之后、还多了一些layoutControlItem组件。

(3) 设置layoutControlItem的标签属性 (text属性) 。

(4) 设置拖拉的常规编辑控件的相关属性, 如DataBindings数据源属性、可见属性、可用 (Enable) 属性、可用 (Visible) 属性等。

对于以上问题, 1和2是很简单的, 直接在设计器中拖拉一下控件, 然后命名它们就可以了。为了后面程序的方便, 这里给定一个规则:LayoutControlItem组件命名时, 以某一个特定的字符串作为前缀, 后面加上数据表的字段名称。在给出的示例项目中, 以“Lab_”作为名字的前缀, 例如对于字段“FieldName”对应的LayoutControlItem, 命名为“Lab_FieldName”。

接下来, 用代码实现对这些LayoutControlItem的属性根据在数据字典中的设置进行赋值即可。

2 代码实现

(1) 设置LayoutControlItem控件的Caption属性以及相关参数的方法。

(2) 接下来设置控件的DataBindingSource数据源, 这是LayoutControlItem控件是否能正确显示数据的关键方法。

到此, 已经准备好了必要的方法, 要调用这些对一个LayoutControl进行设置, 只需在任何需要的地方调用写好的方法即可。

在运行期间进行读写模式、只读模式、隐藏控件3种模式下的程序界面图, 如图1、图2、图3所示。

3 结语

动态控件技术 篇6

当计算机完成某些较复杂的功能时通常需要较长的处理时间, 此时若不动态显示一些信息比如当前任务的完成进度等, 一方面会使用户怀疑是否死机, 另一方面当用户发现操作有误需要中断时也无法进行。Windows风格的进度指示器窗口是复杂软件运行时一种较好的人机交互界面。在基于MFC的系统开发中, Windows进度条控件类CProgress Ctrl是进行指示进度设计的首选, 然而该进度条存在一些不足。例如进度值的显示, 必须事先设置Max、Min属性并通过Pos属性的变化指示进度, 而不能直观地给出百分比进度; 不支持运行过程中用户的“停止”或“取消” 操作等。介绍一种用动态控件技术实现的反显进度指示器, 如图1所示。对其做适当的修改, 可得到满足不同要求的一些进度指示器的变种, 比如用过渡色制作渐变进度指示器或者自适应式光滑进度条。

2 反显设计策略

2.1 自定义进度指示器构成

整个进度指示器由两个进度条组成, 它们大小相同, 位置重叠, 进度条的前景色与背景色互反。为了便于观察清楚,将两个进度条分开, 其显示界面如图2所示。在上面的进度条为红底白字, 在下面的进度条为白底红字。每个进度条包括两个编辑框控件, 一个用于控制显示进度条的背景色, 一个用于控制显示进度条的进度值 (以下分别简称背景编辑框和文本编辑框), 文本编辑框位于背景编辑框的中间位置, 并且设置文本对齐方式为左对齐。

2.2 进度指示器设计思想

进度条反显的设计策略首先是利用控件的重叠显示, 其次是当编辑框长度小于文本长度时, 可以实现文本的部分显示。具体设计思路为:

(1) 下层的进度条以白底红字居中显示进度值 , 并且两个编辑框的大小和位置不变。在定时器函数中控制更新进度值;

(2) 随着进度的增加, 上层进度条的长度随之增加 , 也即背景编辑框长度逐渐增加, 当其长度超过一定值时, 初始化文本编辑框, 以白色字体在与底层文本相同的位置显示其进度值;

(3) 随着进度的增加 , 上层文本编辑框长度也随之增加 ,可显示文本逐渐加宽, 直至与下层文本编辑框长度相 同时 ,上层文本完全覆盖下层文本。

3 实现方法

3.1 动态控件

(1) 动态控件的创建

MFC提供了控件的封装类 , 动态控件对象的创建需要调用其相应类的成员函数Create[4]。CEdit::Create函数原型为 :

BOOL Create( DWORD dw Style, const RECT& rect, CWnd*p Parent Wnd, UINT n ID );

其中参数:

1) dw Style : 指定编辑框控件的样式。

2) rect : 指定编辑框控件的大小和位置 , 可以是CRect对象或RECT结构。

3) p Parent Wnd : 指定编辑 框控件的 父窗口 , 不能为NULL。

4) n ID指定编辑框控件的ID号。

构成进度指示器的4个编辑框控件都采用动态方式进行创建, 同时可以将它们组合为动态控件数组进行管理和使用,如下代码所示:

例如, 以进度条父窗口宽度picwid为参照, 动态创建底层背景编辑框的示例代码为:

(2) 动态资源释放

由于动态控件对象是由new运算符生成的, 它占用的资源不会被程序自动释放, 所以当程序退出时, 需要手工释放。判断编辑框对象指针的值, 若不为NULL, 则使用delete运算符释放该对象资源, 示例代码如下:

3.2 编辑框颜色控制

进度指示器的文本反显效果需要设置底层两个编辑框和上层两个编辑框的背景色相反, 以及文本颜色也相反, 也即底层进度条为白底红字, 上层进度条为红底白字。MFC中编辑框控件的默认背景颜色是白色, 文本颜色是黑色。当框架中的控件重绘时会向父窗口发送一个WM_CTLCOLOR消息,可以使用Class Wizard工具映射该消息响应函数On Ctl Color(),从而可以设置控件的背景颜色和文本颜色。其函数原型为:

HBRUSH On Ctl Color( CDC* p DC, CWnd* p Wnd, UINT n CtlColor );

其中参数:

(1) p DC: 包含了子窗口的显示设备环境的指针 , 可能是临时的。

(2) p Wnd: 当前控件指针。

(3) n Ctl Color: 用于指定控件的类型 , 可取值 : CTLCOLOR_BTN、CTLCOLOR_DLG、CTLCOLOR_EDIT、CTLCOLOR_LISTBOX、CTLCOLOR_MSGBOX、CTLCOLOR_SCROLLBAR、CTLCOLOR_STATIC。

该函数返回的画刷句柄用于重绘控件背景颜色。示例代码如下:

3.3进度条控制

在进度指示器的设计中, 进度条的长度依赖于父窗口的宽度picwid, 如图3所示。只需根据实际任务进度percent更新底层进度条和上层进度条的进度值, 以及上层进度条的背景编辑框的长度。设置文本编辑框宽度为TEXTWIDTH, 文本编辑框在背景编辑框中居中显示。设置进度percent的取值范围为0~1, 若定义底层进度条矩形对象rect Bot, 则上层背景编辑框长度rect Up Wid根据当前进度percent进行更新, 在文本编辑框中显示进度为percent*100%。

3.3.1 底层进度条

底层进度条以白底红字进行显示, 两个编辑框的相对位置和宽度 不变 , 而进度条 的长度需 要参考父 对话框的 宽度picwid, 如图3所示 , 故以此为参数设计Create Bot Edit函数 ,用于创建并显示两个编辑框, 其函数原型为:

void Create Bot Edit(int picwid);

(1) 背景编辑框

若设置宽度为20, 长度为picwid-40, 背景编辑框对象创建代码为:

(2) 文本编辑框

定义CRect rect Bot Text, 文本编辑框对象创建代码为:

3.3.2 上层进度条

上层反显的进度条中的两个编辑框长度都是随着进度动态变化的, 需要重置当前背景编辑框和文本编辑框的大小和进度值。当上层背景编辑框的右边界超过下层文本编辑框的左边界时, 开始显示上层文本编辑框及其进度值。随着进度的增加, 上层文本框长度逐渐增加, 从而使其中的进度值由部分显示到完全显示, 当与下层文本编辑框中的进度值重合时, 由于各自的文本颜色不同而呈现出逐渐反显的效果。

如图4所示, 以当前任务进度percent为参数, 设计上层进度条的实现函数, 通过计算当前背景编辑框窗口的右边界,依次更新进度条的长度和进度值。该函数原型为:

void Create Up Edit(float percent);

(1) 背景编辑框

参照底层背景编辑框, 上层背景编辑框的左上角顶点坐标与其重合, 位置不发生改变, 即左上角坐标为(rect Bot.Top Left().x,rect Bot.Top Left ().y), 每次只需要更新矩形右下角顶点的x坐标。

随着进度增长, 上层背景编辑框的长度rect Up Wid = rectBot.Width () *percent, 上层背景编辑框的右下角坐标为 (rectBot.Top Left() .x + int (rect Up Wid) , rect Bot.Bottom Right() .y)。因此, 定义CRect rect Up, 上层背景编辑框大小设置为:

rect Up.Set Rect (rect Bot.Top Left ().x,rect Bot.Top Left ().y,rect Bot.Top Left().x+int(rect Up Wid),rect Bot.Bottom Right().y);

首次创建并显示rect Up, 示例代码为:

p Edit[2]->Create(ES_CENTER, rect Up, this, IDC_UP);p Edit[2]->Show Window(TRUE);

其后, 随着rect Up Wid的更新, 只需移动上层背景编辑框窗口至新的区域, 即:

p Edit[2]->Move Window(rect[2]);

(2) 文本编辑框

当上层背景编辑框的右下角顶点首次进入下层文本编辑框内部时, 即当rect Up.Bottom Right().x >= rect Bot Text.Top Left().x时才创建并显示上层文本编辑框, 此后若满足rect Up.BottomRight().x<=rect Bot Text.Bottom Right().x, 则只需更新上层文本编辑框的宽度, 也即重设右下角坐标并移动上层文本编辑框窗口至新的区域。此时, 上层文本编辑框的左上角顶点与上层文本编辑框的左上角顶点重合, 上层文本编辑框的右下角顶点与上层背景编辑框的右下角顶点重合, 所以上层文本编辑框的坐标为 ((rect Bot Text.Top Left().x, (rect Bot Text.Top Left().y, rect Up.Bottom Right().x, rect Up.Bottom Right().y)。

随着进度增长, 当上层文本编辑框的右边框超过下层文本编辑框的右边界时, 就不需要再更新上层文本编辑框。因此定义CRect rect Up Text, 上层文本编辑框大小设置为:

rect Up Text.Set Rect(rect Bot Text.Top Left().x,rect Bot Text.Top Left().y,rect Up.Bottom Right().x,rect Up.Bottom Right().y);

首次创建并显示上层文本编辑框, 示例代码为:

p Edit[3]->Create(ES_LEFT, rect Up Text, this, IDC_UPTEXT);p Edit[3]->Show Window(TRUE);

其后, 随着rect Up Wid的更新, 只需移动上层文本编辑框窗口至新的区域, 即:

p Edit[3]->Move Window(rect Up Text);

4 应用接口

使用MFC Class Wizard工具对图1所示进度指示器对话框进行封装, 创建类CProg Bar。设计3个公共接口用于用户对进度条的访问控件。另外, 为了便于对进度指示器的 使用 ,可以将图1所示对话框封装成一个DLL库供其他应用程序进行调用。接口函数如下:

4.1 Initial 函数

该函数用于进行进度指示器的初始化, 包括设置进度指示器窗口标题和子标题, 子标题可对任务进行描述。在Initial函数中主 要调用Create Bot Edit函数创建 并显示底 层进度条 。示例代码如下:

4.2 Update 函数

该函数用于更新底层进度条的进度值, 参数percent为当前任务的完成进度值。在Update函数中调用Create Up Edit函数创建并显示上层进度条。示例代码如下:

4.3 Destroy 函数

用于构成进度指示器的4个编辑框都是动态编辑框控件对象, 它们占用的资源不会被程序自动释放, 因此定义Destroy函数完成进度条资源释放。在该函数中判断编辑框对象指针的值, 若不为NULL, 则使用delete运算符释放该对象资源。示例代码如下:

摘要:Windows风格的进度指示器窗口是复杂软件运行时一种较好的人机交互界面。MFC中的CProgress Ctrl类提供了Windows常用的进度条控件的功能,但在使用中存在一些不足。提出一种进度指示器反显设计策略,采用动态方式创建4个编辑框控件构成进度条,详细阐述底层进度条和上层进度条的实现方法和技巧,利用MFC中的WMCTLCOLOR消息函数实现颜色控制。该进度指示器具有很强的通用性,在应用中根据实际任务进度,通过3个接口函数控制进度条的显示和刷新,使用方便,测试效果良好。

动态控件技术 篇7

关键词:图表控件,油田开发,Chart

在Internet和Web技术迅速发展的大背景下, 油田的应用程序和信息数据都会通过网络这一载体进行运用。在油田信息化的建设中, 对数据的处理和运用愈发精益求精。我们在开发程序的过程中, .NET、Visual Studio及Chart控件, 这些开发平台及技术已经逐步占据主流。此次在厂计算机项目-提高注聚质量管理平台中, 我正是用到Chart控件来完成曲线的开发。

1 开发环境介绍

本论文中的Chart控件就是基于VS2012作为开发环境, 嵌套VB语言、.NET作为编程环境, Oracle是油田数据库环境而使用的重要控件。

1.1 NET简介

.NET是一种建立在通用语言上的程序构架。可用于在服务器上生成功能强大的Web应用程序, 并且可以使它运行在Web应用软件开发者的几乎全部的平台上。.NET重要部分是Visual Studio开发工具。

1.2 Visual Studio简介

Visual Studio提供了一个功能丰富的软件集成开发环境。它包括了整个软件生命周期中所需要的大部分工具。所写的目标代码适用于微软支持的所有平台。

2 Chart控件

2.1 论使用传统方式作图

使用传统方法来创建图表, 其特点是要人工定义每一个数据位置、点线坐标, 这就要非常专业的画图功底和时间来计算。

而在形成图标后, 要放大或者缩小图表, 就会使原图出现失真的情况。

在Visual Studio中, 完成一份完整的图表, 在编译上面就要几百行甚至更多的代码。这会大大增加工作量。

传统方法生成的位图, 其实是在定义图像中所有像素点的数据, 这类方法, 则更多的应用在作图中而非工程作图。

2.2 使用Chart控件作图

Chart控件做为微软公司VS里原生控件的新技术, 其各种优势也是在应用开发中体现出来。

Chart控件在生成图表后, 可以平滑放大或缩小。更可在生成图表后随意切换不同类型的图表, 如柱形图、圆饼图等。灵活性很高。

Chart控件在编译代码时相对于传统方式更是只需十几行, 短小精悍, 更是方便以后优化及改进。

Chart控件生成的矢量图, 这在工程作图中是很常见的。

3 Chart控件在开发中的应用

3.1 完成曲线要调试的几个重要属性

Chart控件ID:给其命名一个唯一的指定名字。

Titles标题:是图表的标题配置, 可以摆到相应的位置方便观看。

Chart Areas图表区域集合:可以理解为是一个图表的绘图区, 在这你可以根据你的需要进行添加多个绘图区, 以方便多项数据的显示。

Legends图例集合:用来标注图形中各个线条或颜色的含义。

Series图表序列 (数据对象集合) :实际呈现的图形形状, 就是由此集合中的每一个图表来构成的。在此属性上, 我们关联Chart Areas属性, 可以显示出在一个或两个绘图区。

3.2 完成曲线的两个方法

我们绘制动态图表显示的内容来源于数据, 因此控件如何从油田数据源获取数据是关键的一步。

数据绑定方法:通过IEnumerable接口进行数据绑定。使用Chart的Databind Table方法控件绑定到一个实现IEnumerable接口的对象, 它会根据数据源的字段自动创建数据系列, 每个字段的数据都会成为一个数据系列, 并添加到chart控件中。

用到这种主动绑定数据集合的方法, 将油田数据库表中指定字段的值绑定到指定的坐标轴上。

3.3 Chart曲线应用

完成查询全部区块按时间、影响因素的影响水量及影响井数的曲线此图, 对于全局掌握、控制注聚、水区的注入时率提供了直观、可靠的依据。

首先, 打开Visual Studio, 从工具箱拖放一个Chart控件, 系统默认ID:chart1。

打开Chart1的属性窗口, 找到Chart Areas属性, 在此集合里面添加Chart Area1、Chart Area2, 然后找到Series属性, 在此属性集合里添加series1、series2, 并使其分别对应Chart Area1、Char t Area2。

接着就来设置图表X、Y轴的标题-X轴表示日期, Y-分别是影响的井数和影响的水量。由此, 基本工作已经做好。

接下来, 就是对生产数据进行处理。

建立所需要的Oracle数据表, 在编译过程中, 调用此数据表中所需要的字段来进行计算、整合, 最后通过字段的特定值来绑定到chart控件上。

最后, 调试通过运行以后, 我们可以得到两条全部工作区从2015年9月17日到10月8日的注入欠注情况的曲线。

4 结语

4.1 Chart是Visual Studio中的原生控件, 其适合用来作工程绘图。

4.2 跟传统在Visual Studio中做曲线相比, 应用Chart来开发应用, 不仅从编译角度上操作简便、快捷, 在操作上也是灵活多变, 提高了工作效率。

参考文献

[1]朱忱, 宋顺林.基于.net的Web应用框架的设计与实现[J].计算机工程与设计, 2006 (8) .

上一篇:砌块生产下一篇:DWDM