技术背景:
项目使用技术:delphi + webservices,后台使用cxf,刚接触项目时十分不适应,之前B/S的习惯是不需要关心form控件与模型字段的映射关系,但这个不是,需要自己从控件一个个取值然后赋值给对象实例,显示的时候再一个个从实例取出然后赋值给form控件,后来设想是否可以像b/s中的form进行自动映射,或者直接从表单里可以获取对象的实例?经过文档查阅以及搜索,发现delphi也有类似于java的反射机制,后来就LeoComponent就诞生了,在表单保存与回显的功能上大大减少了工作量。
后续设计了LeoFormPanel、LeoGrid,以及配套的组件。达到可以两句代码实现表单数据的保存与显示,几行代码即可显示数据列表,配合分页等等,相关的组件有日期框,pagecontrol,pagebar,等等。详细可见API
示例1:
//保存表单
//校验表单必填项是否通过
if (LeoFormPanel1.validForm<>nil) and (LeoFormPanel1.validForm.Count=0) then Exit;
tmpUser:=WSM.USER.Create;
//获取对象实例
LeoFormPanel1.getFormInstance(tmpUser);
//保存对象
WSM.GetWsmWSI().insertUser(tmpUser);
示例2: //查询结果
tmpUsers := WSM.GeWsmWSI().selectUsers() ;
//加载返回结果
LeoGrid1.loadData(@tmpUsers);
示例文档:
unit LeoFormPanel;
{
封装组件:FormPanel
功能示例:
1.getFormFieldValue():TStringList;//获取表单内容键值对字符串
2.getFormFieldValue():TStringList;//获取表单内容键值对字符串
3.getFormInstance(classInstance:TObject):TObject;//获取实例化后的表单内容
4.loadFormData(classInstance:TObject):boolean;//根据传递的实例设置值
5.loadFormDataByList(stringList:TStringList):boolean;//根据传递的list
6.validForm():TStringList;//校验Form中的必填项
7.ItemsEx:TStringList;//设置初始值
示例:
//提交表单
procedure TForm1.BitBtn7Click(Sender: TObject);
var
tmpFunc:User.functionary;
begin
//校验表单必填项是否通过
if (LeoFormPanel1.validForm<>nil) and (LeoFormPanel1.validForm.Count=0) then Exit;
tmpFunc:=User.functionary.Create;
//获取对象实例
LeoFormPanel1.getFormInstance(tmpFunc);
//保存对象
User.GetUserWSI().insertFunctionary(tmpFunc);
tmpFunc.Free;
end;
//加载表单
procedure TForm1.Button4Click(Sender: TObject);
var
tmpFnc:User.functionary;
begin
tmpFnc:= shared.GetUserWSI().selectFunctionaryById(114);
//加载表单
LeoFormPanel1.loadFormData(tmpFnc);
end;
}
unit LeoGrid;
{
封装组件:拓展Grid
功能示例:
属性
1.ExNum:boolean;//是否需要行号
2.Fields:array of string;//字段映射
3.ExCheck:是否显示选择列
方法
1.procedure initHead(Value: array of string);//初始化表头 LeoGrid1.initHead(['第一列','第二列','第三列','第四列','第五列','第六列']); //LeoGrid1.initHead([]);使用ExColumn属性初始化列名
2.procedure setRow(row:Integer;Value: array of string);//设置一行数据 LeoGrid1.setRow(15,['a','b','c','d']);
3.procedure hideColumn(col:Integer);//隐藏一列
4.procedure setColumnWidth(col:Integer;width:Integer);//设置列宽
5.function getColumnValue(col:Integer):String;//获取当前选择行的指定列的值
6.function getCellValueByName(col:String):String;//根据列名获取选择的值
7.procedure loadData(objs:PObjectArray);//加载数据 传递指针 LeoGrid1.loadData(@tmpUser);
8.procedure loadDataByRow(row:Integer;objs:PObjectArray);//根据起始行加载数据
9.procedure loadDataByCount(count:Integer;objs:PObjectArray);//根据指定记录条数加载数据
10.procedure clearData();//清空列表内容
11.procedure setColumnValue(col:Integer;value:String);//根据列设置当前选中行中某列的值
12.procedure setCellValueByName(col:String;value:String);//设置单元格内容
13.procedure deleRow(rowNum:Integer);//删除一行数据
14.function getRow(row:Integer):TStrings;//获取一行数据结果为TStrings
15.function getSelectRowNums(selected:boolean):TArrRowNum;//获取所有选中行的行号
16.function getCellValue(col:Integer;row:integer):String;//获取指定行的指定列的值
//两种方式的调用示例
1.自动配置
1).设置ExColumn属性,示例:[第一列=DID,第二列=DTYPE,第三列=PDID]
2).加载数据
procedure TForm1.Button8Click(Sender: TObject);
var
tmpUser:selectListUserResponse;
begin
//注意:此版本的遗留BUG暂未处理,但不影响使用,如果是在Form的onShow中查询,则需要先手动setFields,原因:onShow执行时ExColumn未执行赋值操作
//LeoGrid1.setFields(['DID','DTYPE','PDID','DCODE','DNAME','DNAMESPELL']);
//查询结果
tmpUser := User.GetUserWSI().selectListUser('','D04000','') ;
//加载返回结果
LeoGrid1.loadData(@tmpUser);
//从第二行开始写数据(指定起始行加载数据)
LeoGrid1.loadDataByRow(2,@tmpUser);
//加载五条数据(指定记录条数加载)
LeoGrid1.loadDataByCount(5,@tmpUser);
end;
2.手动配置
1).//初始化表头
LeoGrid1.initHead(['第一列','第二列','第三列','第四列','第五列','第六列']);
2).加载数据
(1).//添加静态数据
LeoGrid1.setRow(1,['a','b','c','d','e','f']);//第一行增加数据
LeoGrid1.setRow(2,['a','b','c','d','e','f']);
LeoGrid1.setRow(3,['a','b','c','d','e','f']);
(2).//添加后台数据
//手动设置字段映射
LeoGrid1.setFields(['DID','DTYPE','PDID','DCODE','DNAME','DNAMESPELL']);
//查询结果
tmpUser := User.GetUserWSI().selectListUser('','D04000','') ;
//加载返回结果
LeoGrid1.loadData(@tmpUser);
3).其他属性
//根据列获取当前选择行的值
LeoGrid1.getColumnValue(0);
//根据列名获取当前选择行的值
LeoGrid1.getCellValueByName('第三列');
//隐藏第二列
LeoGrid1.hideColumn(1);
//设置列宽
LeoGrid1.setColumnWidth(2,10);
开发人员: wall
日期: 2016年2月4日
}
unit LeoCheckBox;
{
封装组件:拓展CheckBox
功能示例:
1.FieldName //属性:对应生成的Class属性名
2.FieldValue//checkbox值
3.IsRadio //互斥属性,设置后相同字段的相同属性会被互斥
4.Require //必填属性
5.valid():boolean//校验是否正常
6.LeoCheckBox1.GetValueEx();//获取值为:1,2,3
7.LeoCheckBox1.SetValueEx('1,3');//设置多选值
8.EnableEditNameOnCheck//选中时可用的Eidt name 用分号隔开;
9.DisableEditNameOnNotCheck//取消选中时disable的editname 用分号隔开;
10.DisableEditNameOnCheck//选中时需要清空并且disable的Edit控件 用分号隔开;
11.GetTextEx(): string;//获取Text
12.setTextEx(text:string);//根据Text设置值 示例:LeoCheckBox1.SetValueEx('第一项,第三项');
开发人员: wall
日期: 2015年11月17日
}
unit LeoComboBox;
{
封装组件:下拉菜单
功能示例:
1.LeoComboBox1.addItemx('1','测试1');//设置键值对
2.LeoComboBox1.GetValue();//获取键
3.LeoComboBox1.GetText();//获取文字
4.LeoComboBox1.SetValue('3');//设置选中值
5.LeoComboBox1.SetText('测试1');//设置选中内容
6.Require //必填属性
7.valid():boolean//校验是否正常
8.FieldName //属性:对应生成的Class属性名
9.GetStringListValue()//获取下拉框的集合StringList
10.CopyItemByLeoCombox(combox: TLeoComboBox);//根据下拉框复制
}
unit LeoEdit;
{
封装组件:拓展Edit
功能示例:
1.FieldName //属性:对应生成的Class属性名
2.Require //必填属性
3.valid():boolean//校验是否填写数据
}
unit LeoMemo;
{
封装组件:拓展memo
功能示例:
1.FieldName //属性:对应生成的Class属性名
2.Require //必填属性
3.valid():boolean//校验是否填写数据
}
unit LeoLabel;
{
封装组件:拓展Label
功能示例:
1.FieldName //属性:对应生成的Class属性名
}
{
封装组件:日期框
功能示例:
1.LeoDateField1.getValue()//获取日期字符串
2.LeoDateField1.SetValue('2015-06-09');//设置日期字符串
3.LeoDateField1.valid():boolean//校验是否正常1.空校验2.日期格式校验
4.LeoDateField1.SetText('测试1');//设置选中内容
5.Require //必填属性
6.FieldName //属性:对应生成的Class属性名
}