六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 1935|回复: 0

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

[复制链接]

升级  28%

26

主题

26

主题

26

主题

秀才

Rank: 2

积分
92
 楼主| 发表于 2013-1-1 22:28:33 | 显示全部楼层 |阅读模式
业务逻辑与界面元素分离的一次小尝试

<div id="cnblogs_post_body">项目中有一个需求,为单据的表头增加自定义项。受制于现在的架构和表头布局自定义的实现机制,自定义项的内容只能预先在IDE里面创建好,而不能通过代码动态创建,只好在单据基类里面预先放入一组控件。由于自定义项本身需要提供编辑、参照、配置、读取与保存等操作,而基类本身已经臃肿不堪,接这个机会尝试一次界面与业务逻辑分离的尝试。因为架构中本身没有数据访问曾的设计和实现,而这个仅仅是作为一个尝试,因此控制类里面并没有对数据访问这块进行分离。类图如下:

因为自定义项目前支持的是3个,所以定义了一个常量来描述自定义项的个数,以后如果有扩充,修改这个常量即可。
详细代码如下:
<div class="cnblogs_code">  1 {  2   该类用于控制单据表头自定义项。  3   created by fhying@2012.05.04  4 }  5 unit BillTitleCustomItemClass;  6   7 interface  8   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[AItemIndex].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[ItemIndex].itemtype;143       ShowModal;144       if ModalResult = mrOK then145       begin146         FBillTitleCustomItems[AItemIndex].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[RecNo].itemindex := FieldByName('ItemIndex').AsInteger;218       FBillTitleCustomItems[RecNo].itemtype := FieldByName('itemtype').AsInteger;219       FBillTitleCustomItems[RecNo].itemdatasource := FieldByName('itemdatasource').AsString;220       FBillTitleCustomItems[RecNo].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, [FBillType, itemindex, itemtype, itemdatasource, itemdatafield]);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[AItemIndex] do295         szTmp := Format(szTmp, [FBillType, AItemIndex, itemtype, itemdatasource, itemdatafield]);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.
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表