编码笔记 发表于 2013-1-1 22:28:28

业务逻辑与界面元素分离的一次小尝试

业务逻辑与界面元素分离的一次小尝试

<div id="cnblogs_post_body">项目中有一个需求,为单据的表头增加自定义项。受制于现在的架构和表头布局自定义的实现机制,自定义项的内容只能预先在IDE里面创建好,而不能通过代码动态创建,只好在单据基类里面预先放入一组控件。由于自定义项本身需要提供编辑、参照、配置、读取与保存等操作,而基类本身已经臃肿不堪,接这个机会尝试一次界面与业务逻辑分离的尝试。因为架构中本身没有数据访问曾的设计和实现,而这个仅仅是作为一个尝试,因此控制类里面并没有对数据访问这块进行分离。类图如下:
http://images.cnblogs.com/cnblogs_com/codingnote/368759/r_BillTitleCustomItemClass.png
因为自定义项目前支持的是3个,所以定义了一个常量来描述自定义项的个数,以后如果有扩充,修改这个常量即可。
详细代码如下:
<div class="cnblogs_code">1 {2 该类用于控制单据表头自定义项。3 created by fhying@2012.05.044 }5 unit BillTitleCustomItemClass;6 7 interface8 9 uses 10 SysUtils, Classes, Controls, Variants, Dialogs, DB, DBClient, cxEdit, cxDBEdit, 11 Forms, Messages; 12 13 const 14   Const_BillTitleCustomItem_MAX = 3; 15 16 type 17   TBillTitleCustomItem = record 18         itemindex : Integer; {自定义项序号(1-3)} 19         itemtype : Integer; {自定义项类型(0编辑、1参照)} 20         itemdatasource : string; {参照的话,数据来源(目前考虑的是基本信息表,如附加说明)} 21         itemdatafield : string; {参照的话,数据来源的字段} 22   end; 23   TBillTitleCustomItems = array[1..Const_BillTitleCustomItem_MAX] of TBillTitleCustomItem; 24 25   TBillTitleCustomItemClass = class(TComponent) 26   private 27     FcdsSQL : TClientDataSet; 28     FBillType: Integer; 29     FBillTitleCustomItems : TBillTitleCustomItems; 30     FBillTitleCustomDataSource: TDataSource; 31   function GetBillTitleCustomItems: TBillTitleCustomItems; 32   procedure SetBillTitleCustomDataSource(const Value: TDataSource); 33   protected 34   { 根据索引获取自定义项的编辑组件 } 35   function GetButtonEdit(AItemIndex : Integer) : TcxDBButtonEdit; virtual; 36   { 初始化自定义项内容 } 37   procedure InitBillTitleCustomItems; 38   { 创建cds,用于执行sql语句 } 39   procedure CreateCDS; 40   { 保存自定义项配置到数据库 } 41   function SaveBillTitleCustomItems(AItemIndex : Integer = 0) : Boolean; 42   { 从数据库读取自定义项配置 } 43   procedure LoadBillTitleCustomItems; 44   { 为自定义项编辑组件进行事件绑定 } 45   procedure BindcxButtonEdits(AItemIndex : Integer = 0); virtual; 46   { 绑定自定义项组件的按钮单击事件 } 47   procedure PropertiesButtonClick(Sender: TObject; AButtonIndex: Integer); 48   { 执行自定义项编辑组件的参照功能 } 49   procedure Reference(AItemIndex : Integer); 50   { 打开自定义项的配置界面 } 51   procedure CustomConfig(AItemIndex : Integer); 52   { 绑定数据源 } 53   procedure SetEditDataSource; 54   public 55   { 自定义构造函数,传入单据类型。 } 56   constructor CreateMy(AOwnerForm : TComponent; ABillType : Integer); virtual; 57   destructor Destroy; override; 58   { 对外部调用者公布自定义项配置内容 } 59   property BillTitleCustomItems : TBillTitleCustomItems read GetBillTitleCustomItems; 60   { 外部调用者给对象设置数据源 } 61   property BillTitleCustomDataSource : TDataSource read FBillTitleCustomDataSource write SetBillTitleCustomDataSource; 62   end; 63 64 implementation 65 66 uses BillTitleCustomItemForm, un_DM, un_ShowForm, Main, PDWizard, 67 BaseBillA, ProdDw, un_ToolsLC; 68 69 { TBillTitleCustomItemClass } 70 71 procedure TBillTitleCustomItemClass.BindcxButtonEdits(AItemIndex : Integer); 72 var 73 i : Integer; 74   procedure BindcxButtonEdit(AItemIndex : Integer); 75   var 76     AItemType : Integer; 77     AEdit : TcxDBButtonEdit; 78   begin 79   AItemType := FBillTitleCustomItems.itemtype; 80   AEdit := GetButtonEdit(AItemIndex); 81   if AEdit = nil then 82       Exit; 83   case AItemType of 84   0 : { 编辑 } 85       begin 86         AEdit.Properties.Buttons[0].Visible := False; 87         AEdit.Properties.ReadOnly := False; 88       end; 89   1 : { 参照 } 90       begin 91         AEdit.Properties.Buttons[0].Visible := True; 92         AEdit.Properties.ReadOnly := True;       93       end; 94   end; 95   { 用tag来标记是哪个自定义项 } 96   AEdit.Tag := AItemIndex; 97   { 与内置事件绑定 } 98   AEdit.Properties.OnButtonClick := PropertiesButtonClick; 99   end;100 begin101   if AItemIndex = 0 then102   begin103   for i := 1 to Const_BillTitleCustomItem_MAX do104   begin105       BindcxButtonEdit(i);106   end;107   end108   else109   begin110     BindcxButtonEdit(AItemIndex);111   end;112 end;113 114 procedure TBillTitleCustomItemClass.CreateCDS;115 begin116   if FcdsSQL = nil then117   begin118   FcdsSQL := TClientDataSet.Create(nil);119   FcdsSQL.RemoteServer := DM.Con_SubWork;120   FcdsSQL.ProviderName := 'dsp_Oper';121   end;122 end;123 124 constructor TBillTitleCustomItemClass.CreateMy(AOwnerForm: TComponent;125 ABillType: Integer);126 begin127   inherited Create(AOwnerForm);128   FBillType := ABillType;129 InitBillTitleCustomItems;130 LoadBillTitleCustomItems;131 BindcxButtonEdits;132 end;133 134 procedure TBillTitleCustomItemClass.CustomConfig(AItemIndex : Integer);135 var136 frmBillTitleCustomItem: TfrmBillTitleCustomItem;137 begin138   frmBillTitleCustomItem := TfrmBillTitleCustomItem.Create(Application);139   with frmBillTitleCustomItem do140   begin141   try142       ItemType := FBillTitleCustomItems.itemtype;143       ShowModal;144       if ModalResult = mrOK then145       begin146         FBillTitleCustomItems.itemtype := ItemType; // 现在只能设置类型。147         if SaveBillTitleCustomItems(AItemIndex) then148         begin149         { 保存前,已经更新了本地变量,所以不需要再从数据库获取一次。及时性要求不需要这样高。 }150         {LoadBillTitleCustomItems;}151           BindcxButtonEdits(AItemIndex);152         end;153       end;154   finally155       Free;156   end;157   end;158 end;159 160 destructor TBillTitleCustomItemClass.Destroy;161 begin162   if FcdsSQL <> nil then163   begin164     FcdsSQL.Close;165     FcdsSQL.Free;166   end;167   inherited;168 end;169 170 function TBillTitleCustomItemClass.GetBillTitleCustomItems: TBillTitleCustomItems;171 begin172   Result := FBillTitleCustomItems;173 end;174 175 function TBillTitleCustomItemClass.GetButtonEdit(176 AItemIndex: Integer): TcxDBButtonEdit;177 var178   AEditName : string;179 AEdit : TComponent;180 begin181   AEditName := 'edtBillTitleCustomItem' + IntToStr(AItemIndex);182   AEdit := TForm(Owner).FindComponent(AEditName);183   if (AEdit <> nil) and (AEdit is TcxDBButtonEdit) then184   Result := TcxDBButtonEdit(AEdit)185   else186   Result := nil;187 end;188 189 procedure TBillTitleCustomItemClass.InitBillTitleCustomItems;190 var191 i : Integer;192 begin193   for i := 1 to Const_BillTitleCustomItem_MAX do194   begin195   FBillTitleCustomItems.itemindex := i;196   FBillTitleCustomItems.itemtype := 0;197   FBillTitleCustomItems.itemdatasource := 'commoninfo';198   FBillTitleCustomItems.itemdatafield := 'u_Remark';199   end;200 end;201 202 procedure TBillTitleCustomItemClass.LoadBillTitleCustomItems;203 begin204 CreateCDS;205   FcdsSQL.CommandText :=206   'select * from BillTitleCustomItem where billtype = '+IntToStr(FBillType)+' order by ItemIndex';207 FcdsSQL.Open;208   with FcdsSQL do209   begin210   if RecordCount > Const_BillTitleCustomItem_MAX then211   begin212       Exit;213   end;214     First;215   while not Eof do216   begin217       FBillTitleCustomItems.itemindex := FieldByName('ItemIndex').AsInteger;218       FBillTitleCustomItems.itemtype := FieldByName('itemtype').AsInteger;219       FBillTitleCustomItems.itemdatasource := FieldByName('itemdatasource').AsString;220       FBillTitleCustomItems.itemdatafield := FieldByName('itemdatafield').AsString;221 222       Next;223   end;224   end;225 end;226 227 procedure TBillTitleCustomItemClass.PropertiesButtonClick(Sender: TObject;228 AButtonIndex: Integer);229 begin230   case AButtonIndex of231   0 : Reference(TcxDBButtonEdit(Sender).Tag);232   1 : CustomConfig(TcxDBButtonEdit(Sender).Tag);233   end;234 end;235 236 { 因为现在这里只是针对进货单和销售单,且参照仅针对附加说明,所以先这样处理。 }237 procedure TBillTitleCustomItemClass.Reference(AItemIndex : Integer);238 var239   szFieldName : string;240 begin241   if tclientdataset(BillTitleCustomDataSource.DataSet).ReadOnly then242     Exit;243 244   fm_main.vpSingleType := 13;245 246   fm_ProdDw := Tfm_ProdDw.create(application);247   try248   with fm_ProdDw do249   begin250       fm_ProdDw.vpCalltype := 3;251 252       T1_Showmodal(fm_ProdDw);253       if modalresult = mrok then254       begin255         szFieldName := 'Item' + IntToStr(AItemIndex);256       tclientdataset(BillTitleCustomDataSource.DataSet).Edit;257         tclientdataset(BillTitleCustomDataSource.DataSet).FieldByName(szFieldName).AsString := cds_SingleList.FieldByName('U_Remark').AsString;258       tclientdataset(BillTitleCustomDataSource.DataSet).Post;259       end;260   end;261   finally262   gl_Trans.Info1 := '';263     fm_ProdDw.free;264   end;265 end;266 267 function TBillTitleCustomItemClass.SaveBillTitleCustomItems(AItemIndex : Integer): Boolean;268 var269   szSQL : string;270   function MakeSaveSQL : string;271   var272     i : Integer;273   szDelete : string;274   szTmp : string;275   begin276   Result := '';277   if AItemIndex = 0 then278   begin279       szDelete := ' delete from BillTitleCustomItem where BillType = '+IntToStr(FBillType);280 281       for i := 1 to Const_BillTitleCustomItem_MAX do282       begin283         szTmp := ' insert into BillTitleCustomItem (BillType, itemindex, itemtype, itemdatasource, itemdatafield) values (%d,%d,%d,'+Char(39)+'%s'+Char(39)+','+Char(39)+'%s'+Char(39)+')';284         with FBillTitleCustomItems do285         szTmp := Format(szTmp, );286 287         Result := Result + szTmp ;//+ Char(13)+Char(10);288       end;289   end290   else291   begin292       szDelete := ' delete from BillTitleCustomItem where BillType = '+IntToStr(FBillType) + ' and itemindex =' + IntToStr(AItemIndex);293       szTmp := ' insert into BillTitleCustomItem (BillType, itemindex, itemtype, itemdatasource, itemdatafield) values (%d,%d,%d,'+Char(39)+'%s'+Char(39)+','+Char(39)+'%s'+Char(39)+')';294       with FBillTitleCustomItems do295         szTmp := Format(szTmp, );296       Result := Result + szTmp ;297   end;298 299   Result := szDelete + Result;300   end;301 begin302   szSQL := MakeSaveSQL;303   FcdsSQL.CommandText := szSQL;304   try305     FcdsSQL.Execute;306 307   Result := True;308   except309   on e : Exception do310   begin311       Result := False;312       ShowDlg(1, '保存单据表头自定义项设置失败。'+#13+'错误信息:'+#13+e.Message);313   end;314   end;315 end;          316 317 procedure TBillTitleCustomItemClass.SetBillTitleCustomDataSource(318   const Value: TDataSource);319 begin320   FBillTitleCustomDataSource := Value;321 SetEditDataSource;322 end;323 324 procedure TBillTitleCustomItemClass.SetEditDataSource;325 var326 i : Integer;327 AEdit : TcxDBButtonEdit;328 begin329   for i := 1 to Const_BillTitleCustomItem_MAX do330   begin331   AEdit := GetButtonEdit(i);332   AEdit.DataBinding.DataSource := BillTitleCustomDataSource;333   AEdit.DataBinding.DataField := 'Item'+IntToStr(i);334   end;335 end;336 337 end.
页: [1]
查看完整版本: 业务逻辑与界面元素分离的一次小尝试