Sybase公司的PowerBuilder开发工具,在以前VS工具没有成事以前,是相当风光的.微软都要与其合作,学习它Db方面的技术,才成就了SQLServer数据库。PB开发工具的风光得益于它非常强大的数据窗口功能,这个技术的使用,使得开发管理类软件,尤其是开发数据库管理类软件变得异常简单,与使用VS.NET开发同一软件相比较,其开发周期可以缩短至三分之一,只是随着Sybase的没落,技术更新不及时,使得PB开发工具逐渐被遗忘在时间的长河中,很少被人提及和记起.但数据窗口的强大功能,我们仍然可以在NET环境中使用
此组件就是利用数据窗口的强大功能来解决我们常用的业务场景.同时,又封装一层,使用会更加方便.
经过整理和分析,在NET环境中使用的数据窗口中包含如下功能
批量展示数据,支持多种数据加载方式,底部合计带,多选行等实用功能.类似于如下环境中的控件
WebForm/WebMVC |
GridView控件,服务端只包含数据加载 Html中Table组件 |
WinForm |
DataGridView控件 |
将数据直接打印,使用数据窗口制作模板,通过DataTable加载数据,即可打印.尤其在WebForm/WebMVC环境中,不必考虑栏目对象位置,样式等令人头痛的问题.我们可以将复杂报表的样式,包括字段的位置,大小等,全部在数据窗口中设置完成,余下的工作就是加载数据
单据是提供数据编辑的地方,需要根据用户体验不断调整控件布局,大小等,如果每次调整都需要开发员介入会影响用户需求的修改时间.使用数据窗口,我们可以在另外的设计环境中修改,修改完以后可直接交付客户使用,而不必在VS环境中修改
一般在显示批量数据的页面中,我们可能都会提供一些常用检索条件,来帮助用户查找他们最需要的数据.我们在收集检索条件时,可能会将每个检索控件值取出,然后拼接成SQL语句所需的Where条件.
使用数据窗口,检索栏目可以随时增加和删除,检索值可以同一拼接.
DataWindowNet控件可以开发WinForm,WebForm和WebMVC三种场景下的软件,在WebForm/WebMVC程序使用中,作为ActiveX控件,它仍能在IE浏览器中使用.目前支持如下几种应用场景
场景名称 |
描述 |
WebForm/WebMVC应用程序 |
作为ActiveX控件使用 |
WinForm应用程序 |
作为UserControl控件使用 |
此控件的制作环境可以不在VS.NET环境中,只需安装PowerBuilder或运行数据窗口设计器即可完成数据窗口的制作过程.软件实施人员作为程序用户的直接服务者,经过培训1-2天,也可以完成简单的制作.程序的发布和布署也简单方便.因此,除软件开发员之外,实施员也是此控件的面向群体
面向群体 |
描述 |
软件开发员 |
调用控件 |
实施员 |
制作数据窗口,供控件调用 |
Net类库只须2.0及其以上即可.
它本身也和一般的控件相同,只需调用DLL文件即可.DLL环境包含两部分.第1部分是PowerBuilder环境所要求的,由于数据窗口控件是PowerBuilder开发工具中的控件,因此必须包含此部分DLL;第2部分是数据窗口本身所要求的,数据窗口本身如果需要在NET环境中使用,那么就需要将PowerBuilder环境中的数据窗口控件由Sybase公司封装一层,作为NET可以解析的控件使用,这就有了第2部分所需要的DLL文件.详细DLL文件如下所示
DLL文件类型 |
DLL文件列表 |
PowerBuilder应用程序 |
|
DataWindow控件 |
控件本身没有提供Setup安装程序,只需将运行环境和NS前缀的dll文件一并复制至Bin文件夹内,通过Net项目文件的Reference引入即可
l DataWindowControl
这是一个控件的名称,就是我们所封装的这个控件在NET环境中的名称.在PowerBuilder开发环境中,它是叫DataWindow的名字.这个控件可以理解为可视化操作数据窗口的控件,类似于NET中的Panel或GroupBox这类的容器控件.
l DataStore
这是一个对象,此对象的功能与DataWindowControl控件相同,唯一不同的地方:它是不可视化的操作数据窗口的控件,在NET中,它相当于DataSet或DataTable对象的作用,填充并操作数据.
l DataWindowChild
这也是一个对象,如果把DataWindowControl比做是WinForm中DataGridView控件的话,那它就是下拉菜单栏目对象.用法完全相同,需要加载数据,设置数据列和显示列名称.
l DataBuffer
可理解为缓冲区,此控件共包含3个缓冲区,如下所示.一般来说,我们只用到Primary缓冲区,而控件本身默认的数据操作也是在Primary缓冲区中操作的
缓冲区名称 |
描述(官方,英文) |
Primary |
The data in the primary buffer, meaning data that has not been deleted or filtered out. (Default value when argument is optional.) |
Delete |
Data in the delete buffer, meaning data that has been deleted from the DataWindow but has not been committed to the database. |
Filter |
Data in the filter buffer, meaning data that has been removed from view. |
l RowStatus
枚举对象,即数据窗口行状态,相当于NET中的DataRowState枚举对象.属性值包含如下:
枚举对象 |
描述 |
Modified |
处于修改状态的行 |
New |
处于新增状态的行 |
NewAndModified |
处于新增和修改状态的行 |
NotModified |
没有操作的行状态 |
l ItemStatus
枚举对象,与RowStatus功能一致,它是栏目状态.即数据窗口某行中的某个栏目是否被修改.NET中并没有找到与之类似的枚举对象.属性值包含如下:
枚举对象 |
描述 |
Modified |
处于修改状态的栏目 |
NotModified |
没有操作的栏目状态 |
l Processing
这是一个数据窗口的属性,此属性表示控件所加载的数据窗口是类型,控件本身是不知道它所要加载的数据以何种方式展示,有可能是批量数据(Grid类型),有的是单条数据(Form类型),因此设置了这个属性用于区分.属性值包含如下:
类型 |
描述 |
Form |
单条数据展示 |
Grid |
批量数据展示,类似于网格控件 |
Label |
标签,类似于超市里的商品标签 |
Graph |
图表,控件也可以直接加载图表 |
Crosstab |
交叉报表,对Db中某张表直接可以设置行列交叉 |
Composite |
复合报表.即此类型的数据窗口中可以同时放置其他类型的数据窗口,作为子表使用.如:可同时放置Grid和Form |
OLE |
可以把数据直接放至OLE控件,OLE控件必须是PowerBuilder支持的 |
RichText |
可以把数据直接放至RichText控件中 |
TreeView |
这个类型的数据展示,是最近比较火的一种展示方式.即网格控件中的父子表.简单理解,父子表也是有层级关系的,与树相比,每级可能需要展示不止一个结点, |
l ItemEditStyle
数据窗口中对象的编辑类型.即表示对象是文本框,直线或图片框等.其属性值包含如下
枚举对象 |
描述 |
Text |
标签,可理解为NET中的Label |
Column |
Db列对象,可理解为NET中的TextBox |
Line |
直线 |
Bitmap |
图片框 |
Compute |
计算列 |
l Item
这是一个关键字,会更贴切一点.在封装的类库中,会看到很多GetItemXX和SetItemXX的方法.这里的Item可理解为项目,子项,即数据窗口中某个对象,可能是直接,可能是文本框或图片框
l Sub
这是一个关键字,只适用在复杂类型的数据窗口中.复合类型的数据窗口是可以同时放置其他数据窗口,那么这其中的数据窗口就是用Sub来表示.这是为了与Item关键字有所区别,因为他们的含义有所不同
使用此控件可以很方便的帮助我们完成很多常用的业务场景,在此针对常用的业务场景,提供代码示例和说明注释
就是将Db或其他外部文件的数据填充至数据窗口控件中,此类库中提供6种方式实现数据加载.即有PB的传统方式,也有基于NET的方式,使用时需要根据不同的业务场景来确定用哪种方式
在加载数据之前,我们首先要对控件设置两个属性.即它所加载的数据所需要的载体文件名称和对象.可以理解为承载数据的可视化窗口名称及其所在DLL文件名称.使用如下方式加载即可,如图-1所示
图-1
l 方式一.如图-2所示
图-2
1. DataWindow控件在数据加载时,也有一个事务的对象,用于连接Db的.就是Transaction对象,与NET中的Transaction对象作用相似,设置一个Db连接字符串,将事务对象绑定至控件,再刷新一下即可
2. 此种方法目前仅支持SqlServer数据库,而且最好在WinForm应用程序中使用.此控件中的事务与NET的事务有所区别,它是常连接Db的,而NET的事务是使用一次连接一次,这是最大的区别.所以使用此方法对连接Db的带宽会有影响.
3. 注意提供的Db连接字符串格式,包含如下四个关键字(注:大小写不区分)
关键字 |
描述 |
Data Source |
SqlServer服务名称 |
Database |
数据库名称 |
User id |
登录用户ID |
PWD |
登录用户密码 |
l 方式二.如图-3所示
图-3
1. 这个方式应该是Sybase为了适应NET而新增的对象,在Sybase自带的PowerBuilder开发工具中是没有这个对象的,而且此控件刚在NET上使用的时候,ADO.NET的Db连接方式是最流行的,所以会有此控件
2. 与方式一中的Transaction对象使用方法完全一致,注意它的关键字与方式一的区别是使用了Server这个关键字作为服务器名称
3. 关键字说明(不区分大小写)
关键字 |
描述 |
Server |
SqlServer服务名称 |
Database |
数据库名称 |
User id |
登录用户ID |
PWD |
登录用户密码 |
l 方式三.如图-4所示
图-4
1. 此种方式是纯NET的方式,加载一个DataTable对象,然后直接刷新控件即可
l 方式四.如图-5所示
图-5
1. 此种方式是使用InsertRow方式增加数据,可用在加载单条数据
2. 可使用在WebForm应用程序中,在后台获取数据,使用Ajax方式传递给前台,在前台通过InsertRow方式加载即可.这是因为在WebForm应用程序中,我们是以Active控件方式使用的,在后台是不能操作控件的
l 方式五.如图-6所示
图-6
1. DataWindowFullState对象可理解为二进制数据类型.它可以将控件的所有结构和数据一并存储到这个对象中,然后通过复制的方式一并传递给另一个对象
2. WebForm应用场景中也可以使用此方法
l 方式六.如图-7所示
图-7
1. 控件本身有2个方法,专门用来过滤数据,即SetFilter和Filter.
2. 使用此方法,首先将所有数据加载至此,然后就可以使用此方法,设置查询条件检索数据,如果条件为空,则检索出所有数据
栏目的取值,我们一般只需获取两种栏目类型的值就可以了.分别是Column和Compute.类库中也提供了若干方法支持栏目的取值和赋值操作.
方法类型 |
方法名称 |
描述 |
取值 |
GetItemDeciaml |
获取栏目类型为Decimal类型的栏目值 |
GetItemDouble |
获取栏目类型为Double类型的栏目值 |
|
GetItemDateTime |
获取栏目类型为DateTime类型的栏目值 |
|
GetItemString |
获取栏目类型为String类型的栏目值 |
|
GetItemObject |
获取栏目值,不区分栏目类型 |
|
GetItemObjectText |
获取栏目显示值,下拉菜单编辑类型栏目专用 |
|
GetItemExpression |
获取计算字段表达式,计算字段专用 |
|
赋值 |
SetItemNull |
设置栏目值为Null |
SetItemObject |
设置栏目值,Object类型 |
|
SetItemExpression |
设置栏目表达式,只对计算字段 |
所谓级联操作,就是某个控件值会根据另外一个控件值的变化而变化,一般最常见的常景要属省市区的联动效果.现使用此控件模拟此业务场景,场景如下描述
两个栏目,分别是省和市,均为下拉菜单编辑类型.其中,省填充北京市和天津市;市中的数据根据北京市或天津市,加载下面的区县.如:北京市,东四区;天津市,红桥区.界面如图-8所示.选择省部分的下拉菜单,市的数据会跟着联动
图-8
复合报表,一般用于制作复杂结构的数据窗口,例订打印票据,需要表头数据,明细数据和表尾数据.也就是说,需要由3部分组成.普通的数据窗口是没有此功能的,要么都是表头的Form数据窗口,要么都是明细数据的Grid数据窗口.而复合数据窗口就可以解决此问题,而且也可以通过可视化设计实现.在如图-22所示的页面中,选择需要的子数据窗口即可.
图-22
这里我们选择如下3个数据窗口,作为复合数据窗口的表头,表体和表尾.
名称 |
描述 |
d_example_composite_head_bl |
复合数据窗口表头文件 |
d_example_composite_body_bl |
复合数据窗口表体文件 |
d_example_composite_foot_bl |
复合数据窗口表尾文件 |
加载数据方式也比较简单,如图-23所示,如同加载下拉菜单的数据相同,如图-23所示
图-23
看下最图的效果图,如图-24所示
图-24
所谓动态创建对象,就是根据某个控件中的数据窗口,在另外的模板文件中动态创建对象.这个业务场景适用于复合数据窗口打印,由于复合数据窗口是由多个子数据窗口组合而成,因此打印也只能打印其中一个,如果全部打印的话,就需要将每个子数据窗口的对象动态生成至一个打印数据窗口才可以.
可动成生成的对象即是ItemEditStyle的样式,这几种编辑类型的对象均是可以动态生成的.调用方法名称如图-18所示.只需传入对象名称即可,也可以同时获取多个对象,也可以获取某一编辑类型的所有对象生成语句
图-18
创建的方式很简单,我们只需调用Modify方法即可.一般这个方法与Describe方法一并使用,主要处理数据窗口中的对象属性值的取值和赋值.在提供的示例页面中,如图-19所示.对每个编辑类型的对象,生成的Create语句都有所描述
图-19
交叉表的使用,可以帮助我们快速分析数据,但由普通的二维表转为复杂的交叉表,需要有一定功力的开发员才可以.此控件可以以向导的方式可视化地将一个普通的二维表转为交叉表的形式.模拟表结构如图-9所示.模拟学生的学科成绩
图-9
我们来看看制作向导,这就用到PowerBuilder的开发工具了.创建的数据窗口类型选择CrossTab类型之后,在如图-10选择行列关系时,这样选择就可以了.
图-10
只要定义好所需要的行列栏目名称,以及交叉后需要显示的值就可以了,设计效果图如图-11所示
图-11
最后,我们要做的事情,就是填充数据,填充的数据是普通的二维表数据,不必是交叉后的表数据.填充数据的方式要说明下:采用PB的传统方式加载,不是通过DataTable对象加载就可以了.如图-12所示
图-12
看,就是这样简单.整个流程最复杂的设计环节交由可视化的设计器实现,我们只需写代码加载数据即可.最终效果图如图-13所示
图-13
父子表的功能,关键是看网格控件是否支持,值得庆幸的是,此控件我们可以模拟出父子表的效果,我们采用的思路是TreeView类型的数据窗口,这个类型的数据是在PB10以后才增加的内容,使用效果也不错.父子表简单说就是树的一种扩展,树里面是只显示某一个栏目值,而父子表在同一级别中要求同时显示多个栏目值,此类型的数据窗口就实现了同时展示多个栏目.制作过程如下.
步骤1:准备做为父子表的数据源,这里采用Northwind数据库中的Orders和Order Details表,表结构定义如图-14所示
图-14
步骤2:制作数据窗口,在选择TreeView类型的数据窗口后,选择数据源,在如图-15所示的页面中,右侧的栏目名称列表就是我们作为父级数据的栏目名称,这里选择OrderID,CustomerID,EmployeeID和OrderDate四个字段即可.OK,整个过程制作完成,我们看看设计时的效果图,需要美观的话,可以再加载一下,如图-16所示
图-15
图-16
步骤3:加载数据,使用PB的传统方式或NET方式均可.最终效果如图-17所示
图-17
数据窗口也是支持图表功能的,而且也十分强大,图表类型支持很多种,包含如下图表类型.如图-20所示
图-20
制作流程与制作一般数据窗口一致,在如图-21的页面中选择好XY坐标所需要的值即可,生成的最终效果图如图-22所示
图-21
图-22
数据窗口最大的优势就是可以像WinForm开发那样,随意拖拉控件,即使在WebForm/WebMVC场景中,从而不必考虑样式布局等.如下图-23所示
图-23
本控件提供的示例解决方案,其开发环境:VS2012+Net.4.0
示例解决方案说明
名称 |
描述 |
Navi.Soft30.Product.DataWindowNet |
解决方案 |
NS.Product.DataWindowNet.Service |
DataWindow控件服务类封装 |
NS.Product.DataWindowNet.WinUI |
WinForm场景中UI页面 |
NS.Product.DataWindowNet.ZLaunch |
WinForm场景示例 |
NS.Product.DataWindowNet.ZLaunch.WebForm |
WebForm场景示例 |
NS.Product.DataWindowNet.ZLaunch.WebMVC |
WebMVC场景示例 |
问:控件可以在什么开发环境下使用?
答:控件可以在WebForm和WinForm均可以使用.在WinForm控件中,作为自定义控件使用;在WebForm控件中作为ActiveX控件使用,并且只可以在以IE为内核的浏览器中使用.如下图-24和图-25所示
图-24
图-25
问:控件是基于PowerBuilder开发工具什么版本?
答:控件是基于PowerBuild11.5的版本
问:批量数据窗口中的数据行号是从0还是1开始?
答:是从1开始.与NET的起使有所区别,这是因为Sybase的PowerBuilder开发工具要早于NET出现