delphi开发回忆录——面向对象的基础,继承(续)
在事件中声明
var
testform:TfrmBasic;
并创建窗体对象,然后进行赋值操作,从前面的代码中我们不难看出这样写程序有太多的弊端,比如:代码重复,死板等等。
其实我们可以通过TRzGroupBar控件的TRzGroupItem对象的Tag或者Caption来创建相应的窗体对象,例如:
procedure TfrmMain.rgBaseDatumItems0Click(Sender: TObject);
begin
CreateFormSelect(Sender);
end;
函数CreateFormSelect如下:
procedure TfrmMain.CreateFormSelect(Sender: TObject);
begin
MsgBox((Sender as TRzGroupItem).Caption,0);
end;
根据上面,我们在全局单元文件中创建一个创建窗体对象的函数:Procedure CreateForm(TBTag:Integer;aCaption:String);
然后在CreateFormSelect中调用CreateForm,如下:
procedure TfrmMain.CreateFormSelect(Sender: TObject);
begin
CreateForm(TRzGroupItem(Sender).tag,(Sender as TRzGroupItem).Caption);
end;
我们可以在过程CreateForm中对所创建的窗体不同而赋相应的对象,比如设置控件的显示,赋于不同的数据集对象等等
接下来,我们在数据窗体中放入两组ADOQuery和DataSource分别命名为:dsEmployee,qryEmployee和dsDepartment,qryDepartment,然后设置dsEmployee的Dataset属性为qryEmployee,dsDepartment的Dataset属性为qryDepartment,再设置qryEmployee和qryDepartment的SQL属性分别为:
select * from Employee和select * from Department,当然需要在数据库分别创建表Employee和Department。
函数CreateForm根据传入的参数不同而创建不同类型的三种窗体:基本资料窗体,单据窗体和报表窗体,代码如下:
Procedure CreateForm(TBTag:Integer;aCaption:String);
begin
case TBTag of
100..199:
begin
CreateBasicForm(TBTag,aCaption);
end;
200..299:
begin
CreateBillForm(TBTag,aCaption);
end;
300..399:
begin
CreateReportForm(TBTag,aCaption);
end;
end;
end;
在此代码中我们发现调用了CreateBasicForm,而这个方法才是我们真正创建基本资料窗体的函数,现在来揭开她的神秘面纱,看她到底有什么魔力。
Procedure CreateBasicForm(TBTag:Integer;aCaption:String);
var
LableList,LableDetail:string;
tempstr:string;
begin
Case TBTag of
100:
begin
LableList:='员工列表';
LableDetail:='员工资料';
frmDM.dsMaster:=frmDM.dsEmployee;
end;
101:
begin
LableList:='部门列表';
LableDetail:='部门资料';
frmDM.dsMaster:=frmDM.dsDepartment;
end;
end;
LockWindowUpdate(frmMain.Handle);
if Assigned(vBasicForm) then
begin
MsgBox('窗体创建错误!',MB_ICONINFORMATION);
exit;
end;
if Not Assigned(vBasicForm) then
begin
vBasicForm:=TfrmBasic.Create(Application);
vBasicForm.Caption:=aCaption;
with vBasicForm do
begin
dbgrdhList.DataSource:=frmDM.dsMaster;
dxdbinsEdit.DataSource:=frmDM.dsMaster;
end;
frmDM.dsMaster.DataSet.Active:=True;
with vBasicForm.dbgrdhList do
begin
Columns.Clear;
Columns.Add;
Columns[0].Title.Caption:=copy(LableList,1,4)+'编码';
Columns[0].Width:=100;
Columns[0].FieldName:=frmDM.dsMaster.DataSet.Fields[1].FieldName;
Columns.Add;
Columns[1].Title.Caption:=copy(LableList,1,4)+'名称';
Columns[1].Width:=160;
Columns[1].FieldName:=frmDM.dsMaster.DataSet.Fields[2].FieldName;
end;
InitDataSetInspectorl(frmDM.dsMaster.DataSet.Tag);
vBasicForm.Show;
end
else
vBasicForm.show;
LockWindowUpdate(0);
end;
从代码中可以看出,根据传入的参数,来对一些变量进行赋值,特别注意的一行代码是frmDM.dsMaster:=frmDM.dsEmployee;
此行代码是对数据组件窗体中的组件进行赋值,目的是为了在基窗体中引用的类TBaseClass中的数据操作保证是对相同的数据集操作。
回顾一下TBaseClass类中对数据的操作,都是对数据窗体中的dsMaster数据源进行操作的。因为我们在窗体时要将相应的数据源码赋值给数据窗体中的dsMaster数据源。继续看代码,可以知道已经将数据窗体中的dsMaster数据源赋值到创建窗体中的dbgrdhList和dxdbinsEdit控件,代码如下:dbgrdhList.DataSource:=frmDM.dsMaster;
dxdbinsEdit.DataSource:=frmDM.dsMaster;
接下来的代码是对两个数据显示控件进行初始化,而dxdbinsEdit则是通过方法InitDataSetInspectorl进行初始化,方法InitDataSetInspectorl的源码如下:
Procedure InitDataSetInspectorl(TableTag:Integer);
var
i,j,TempWidth,MaxWidth:integer;
StrTableID,StrList:String;
TempQuery:TADOQuery;
TableValue:Boolean;
varRow:integer;
vFL:integer;
vFieldList:array [0..19] of String;
begin
StrTableID:=GetFieldName(TableTag,2);
StrTableID:='01';
TempQuery:=TADOQuery.Create(Application);
Try
TempQuery.Connection:=frmDM.conDB;
TempQuery.SQL.Clear;
TempQuery.SQL.Text:=Format('Select * From DataDictContent where TableID=''%s'' order by TableID,FieldID',[StrTableID]);
TempQuery.Open;
i:=0;
MaxWidth:=0;
if vBasicForm.dxdbinsEdit.TotalRowCount>0 then
vBasicForm.dxdbinsEdit.ClearRows;
if Not TempQuery.IsEmpty then
While Not TempQuery.Eof do
begin
if TempQuery.FieldByName('DisplayFlag').AsBoolean then
with vBasicForm do
with dxdbinsEdit do
begin
BeginUpdate;
DefaultFields := False;
case TempQuery.FieldByName('InspectorRowType').AsInteger of
0:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBRow,TempQuery,0); //TdxInspectorDBRow 类型引用单元文件dxDBInsp
1:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBRow,TempQuery,1);
2:
CreateInspectRow(dxdbinsEdit,TdxInspectorComplexRow,TempQuery,2); //TdxInspectorComplexRow 类型引用单元文件dxInspct
3:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBMaskRow,TempQuery,3);
4:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBDateRow,TempQuery,4);
5:
CreateInspectRow(dxdbinsEdit,TdxInspectorLookupRow,TempQuery,5);
6:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBCheckRow,TempQuery,6);
7:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBCalcRow,TempQuery,7);
8:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBButtonRow,TempQuery,8);
9:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBSpinRow,TempQuery,9);
10:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBPickRow,TempQuery,10); //TdxInspectorDBPickRow 类型引用单元文件dxDBInRw
11:
CreateInspectRow(dxdbinsEdit,TdxInspectorBlobRow,TempQuery,11);
12:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBImageRow,TempQuery,12);
13:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBTimeRow,TempQuery,13);
14:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBCurrencyRow,TempQuery,14);
15:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBHyperLinkRow,TempQuery,15);
16:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBPopupRow,TempQuery,16);
17:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBMRURow,TempQuery,17);
18:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBMemoRow,TempQuery,18);
19:
CreateInspectRow(dxdbinsEdit,TdxInspectorDBGraphicRow,TempQuery,19);
else
CreateInspectRow(dxdbinsEdit,TdxInspectorDBRow,TempQuery,1);
end;
EndUpdate;
end;
TempQuery.next;
end;
finally
TempQuery.Free;
end;
end;
上面方法又调用了CreateInspectRow方法,代码如下:
procedure CreateInspectRow(varDBInspector:TdxDBInspector;IR: TdxInspectorRowClass;
varADOQuery:TADOQuery;RowFlag:integer);
var
RowButton:TdxEditButtonClass; //TdxEditButtonClass类型所引用单元文件dxExEdtr
varInt:integer;
StrList:string;
j:integer;
begin
with varDBInspector do
with TdxInspectorDBRow(CreateRow(IR)) do
begin
Caption:=varADOQuery.FieldByName('DisplayCaption').AsString;
FieldName :=varADOQuery.FieldByName('FieldName').AsString;
if varADOQuery.FieldByName('ReadOnlyFlag').AsBoolean then
ReadOnly:=True;
name:='ir'+FieldName;
if RowFlag=8 then
begin
varInt:=varDBInspector.IndexOfRow(varDBInspector.RowByName(Name));
(varDBInspector.Rows[varInt] as TdxInspectorDBButtonRow).OnButtonClick:=frmBasic.DBInspectorRowOnButtonClick;
end;
if FieldName='Password' then
PasswordChar:='*';
if RowFlag=10 then
if varADOQuery.FieldByName('DictionaryFlag').AsBoolean then
begin
if varADOQuery.FieldByName('DictionaryType').AsBoolean then
begin
//Items[i].ButtonStyle:=ibsAuto;
//Items[i].PickList.Clear;
varInt:=varDBInspector.IndexOfRow(varDBInspector.RowByName(Name));
StrList:=varADOQuery.FieldByName('DictionaryTypeID').AsString;
j:=POS(';',StrList);
while j<>0 do
begin
(varDBInspector.Rows[varInt] as TdxInspectorDBPickRow).Items.Add(Copy(StrList,1,j-1));
//Items[i].PickList.Add(Copy(StrList,1,j-1));
StrList:=Copy(StrList,j+1,Length(StrList)-j);
j:=POS(';',StrList);
end;
end
//else
//Items[i].ButtonStyle:=ibsEllipsis;
end;
end;
end;
上面两个过程代码较多,其实也很简单,只要对控件TdxDBInspector多了解一下就会明白。主要是动态创建数据字段。在此不再多做介绍。
上面代码中有这样两行代码:
StrTableID:=GetFieldName(TableTag,2);
StrTableID:='01';
显然有些问题,既然通过函数赋值,那为什么又对StrTableID赋值为'01'呢?
还有对数据显示控件TdxDBInspector进行初始化显示时用到的DataDictContent 表,等等问题,下次再做介绍