查询条件的封装(小结)

来源:岁月联盟 编辑:exp 时间:2012-04-26

截至今天,查询条件的封装第一阶段的工作基本完成了。在之前的基础上做了一些调整,由于D7与XE/XE2的差异,某些思路也做了调整。查询条件项的驱动控制由于是使用TCollection和TCollectionItem来实现的,所以不能作为查询条件项的属性来进行选择(应该是只有继承自TComponent的组件才可以作为属性的选择对象),取而代之的是采用Index的方式来进行绑定,这个我觉得是设计上的一个缺陷,并没有完全符合我最初的设想,在使用上不够简便直观。如果是在XE2下可以有更好的选择,可以用TCustomAttribute加反射机制来实现持久化配置数据的动态绑定。
  常量单元ConditionConst.pas
 
 1 {本单元用于定义基本的数据类型}
 2
 3 unit ConditionConst;
 4
 5 interface
 6
 7 uses
 8   Controls;
 9
10 type
11   TConditionActionIndex = integer;
12   // 查询条件项的编辑模式
13   TConditionEditType = (cetEdit, cetButtonEdit, cetDatePicker, cetComboBox);
14
15   // 查询条件项的值的数据类型
16   TConditionItemDataType = (cidtString, cidtInt, cidtFloat, cidtDouble,
17     cidtDate, cidtDateTime, cidtBool);
18
19   { 定义一组事件 }
20   (* 单击编辑框按钮事件 *)
21   TPropertiesButtonClickEvent = procedure(Sender: TObject; AButtonIndex: Integer) of object;
22   (* 编辑值合法性检测事件 *)
23   TPropertiesValidate = procedure(Sender: TObject;
24       var DisplayValue: Variant; var ErrorText: TCaption;
25       var Error: Boolean) of object;
26   (* 下拉框菜单关闭事件 *)
27   TPropertiesCloseUp = procedure(Sender: TObject) of object;
28   { 查询条件类型 }
29   TConditionType = (cdtCustom, cdtBeginDate, cdtEndDate, cdtUnit, cdtProduct, cdtEmployee,
30     cdtStock, cdtDepartment, cdtArea, cdtBillSN, cdtBillJSR, cdtBillAuditor);
31
32   TConditionTypeItem = record
33     ConditionName : string;
34     ConditionTypeName : string;
35     ConditionEditType : TConditionEditType;
36     ConditionItemDataType : TConditionItemDataType;
37   end;
38
39 const
40   gConditionName : array[0..11] of string = ('TConditionItemX', 'BeginDate', 'EndDate', 'UnitFullID', 'ProdFullID', 'EmpFullID',
41     'StockFullID', 'DeptFullID', 'AearFullID', 'BillSN', 'BillJSR', 'BillAuditor');
42
43   gConditionTypeName : array[0..11] of string = ('查询条件', '开始日期', '结束日期', '往来单位', '商品', '职员',
44     '仓库', '部门', '地区', '单据编号', '经手人', '审核人');
45
46   gConditionEditType : array[0..11] of TConditionEditType = (cetButtonEdit, cetDatePicker, cetDatePicker, cetButtonEdit, cetButtonEdit, cetButtonEdit,
47     cetButtonEdit, cetButtonEdit, cetButtonEdit, cetButtonEdit, cetButtonEdit, cetButtonEdit);
48
49   gConditionItemDataType : array[0..11] of TConditionItemDataType = (cidtString, cidtString, cidtString, cidtString, cidtString, cidtString,
50     cidtString, cidtString, cidtString, cidtString, cidtInt, cidtInt);
51 implementation
52
53 initialization
54
55 end.
 
这里对预置的标准查询条件项采取了数组定义的方式,只是为了验证技术环节是否通畅,这里最终应该考虑和数据的绑定。
  查询条件项定义TConditionItem
 
 1   TConditionItem = class(TCollectionItem)
 2   private
 3     FConditionName: string;
 4     FConditionLabel: string;
 5     FConditionValueType: TConditionItemDataType;
 6     FConditionEditType: TConditionEditType;
 7     FConditionValue: Variant;
 8     FItems: TStrings;
 9     FConditionActionIndex: TConditionActionIndex;
10     FConditionType: TConditionType;
11     procedure SetConditionEditType(const Value: TConditionEditType);
12     procedure SetConditionLabel(const Value: string);
13     procedure SetConditionName(const Value: string);
14     procedure SetConditionValueType(const Value: TConditionItemDataType);
15     procedure SetConditionValue(const Value: Variant);
16     procedure SetItems(const Value: TStrings);
17     procedure SetConditionActionIndex(const Value: TConditionActionIndex);
18     procedure SetConditionType(const Value: TConditionType);
19   protected
20     procedure SetIndex(Value: Integer); override;
21   public
22     constructor Create(Collection: TCollection); override;
23     destructor Destroy; override;
24     procedure Assign(Source: TPersistent); override;
25     property ConditionValue : Variant read FConditionValue write SetConditionValue;
26   published
27     property ConditionName : string read FConditionName write SetConditionName;
28     property ConditionLabel : string read FConditionLabel write SetConditionLabel;
29     property ConditionEditType : TConditionEditType read FConditionEditType write SetConditionEditType;
30     property ConditionValueType : TConditionItemDataType read FConditionValueType write SetConditionValueType;
31     property Items : TStrings read FItems write SetItems;
32     property ConditionActionIndex : TConditionActionIndex read FConditionActionIndex write SetConditionActionIndex;
33     property ConditionType : TConditionType read FConditionType write SetConditionType;
34   end;
 
  查询条件项实现TConditionItem
 
  1 { TConditionItem }
  2
  3 procedure TConditionItem.Assign(Source: TPersistent);
  4 begin
  5   if Source is TConditionItem then
  6   begin
  7     if Assigned(Collection) then Collection.BeginUpdate;
  8     try
  9       //RestoreDefaults;
 10       ConditionName := TConditionItem(Source).ConditionName;
 11       ConditionLabel := TConditionItem(Source).ConditionLabel;
 12       ConditionEditType := TConditionItem(Source).ConditionEditType;
 13       ConditionValueType := TConditionItem(Source).ConditionValueType;
 14     finally
 15       if Assigned(Collection) then Collection.EndUpdate;
 16     end;   
 17   end
 18   else
 19     inherited Assign(Source);
 20 end;
 21
 22 constructor TConditionItem.Create(Collection: TCollection);
 23 begin
 24   try
 25     inherited Create(Collection);
 26     FConditionActionIndex := -1;
 27     FConditionType := cdtCustom;
 28     {FItems用于记录查询条件通过列表选择时的内容}
 29     FItems := TStringList.Create;
 30     FConditionName := Self.ClassName+IntToStr(Collection.Count);
 31     FConditionLabel := '查询条件'+IntToStr(Collection.Count);
 32     FConditionValueType := cidtString;
 33     FConditionEditType := cetButtonEdit;
 34     if Collection is TConditionItems then
 35     begin
 36       if TConditionItems(Collection).FConditionUI <> nil then
 37         TConditionItems(Collection).FConditionUI.BuildConditionGridByItems;
 38     end;
 39   finally
 40
 41   end;
 42 end;
 43
 44 destructor TConditionItem.Destroy;
 45 begin
 46   FItems.Free;
 47   inherited;
 48 end;
 49
 50 procedure TConditionItem.SetConditionActionIndex(const Value: TConditionActionIndex);
 51 //var
 52 //  AConditionController : TConditionController;
 53 //  nActionCount : integer;
 54 begin
 55   FConditionActionIndex := Value;
 56   {
 57   if Collection is TConditionItems then
 58   begin
 59     if TConditionItems(Collection).FConditionUI <> nil then
 60     begin
 61       AConditionController := TConditionItems(Collection).FConditionUI.ConditionController;
 62       if AConditionController <> nil then
 63       begin
 64         nActionCount := AConditionController.ConditionActions.Count;
 65         if (Value < 0) (Value >= nActionCount) then
 66           raise Exception.Create('Out Of Index of ConditionActions.')
 67         else
 68           FConditionActionIndex := Value;
 69       end;
 70     end;
 71   end;
 72 }
 73 end;
 74
 75 procedure TConditionItem.SetConditionEditType(
 76   const Value: TConditionEditType);
 77 begin
 78   FConditionEditType := Value;
 79 //  Changed(False);
 80 end;
 81
 82 procedure TConditionItem.SetConditionLabel(const Value: string);
 83 begin
 84   FConditionLabel := Value;
 85   Changed(False);
 86 end;
 87
 88 procedure TConditionItem.SetConditionName(const Value: string);
 89 begin
 90   FConditionName := Value;
 91 //  Changed(False);
 92 end;
 93
 94 procedure TConditionItem.SetConditionType(const Value: TConditionType);
 95 begin
 96   FConditionType := Value;
 97   if Value <> cdtCustom then
 98   begin
 99     Collection.BeginUpdate;
100
101     ConditionLabel := gConditionTypeName[Ord(FConditionType)];
102     ConditionName := gConditionName[Ord(FConditionType)];
103     ConditionEditType := gConditionEditType[Ord(FConditionType)];
104     ConditionValueType := gConditionItemDataType[Ord(FConditionType)];
105    
106     Collection.EndUpdate;
107   end;
108 end;
109
110 procedure TConditionItem.SetConditionValue(const Value: Variant);
111 var
112   nIndex : Integer;
113 begin
114   FConditionValue := Value;
115 //  Changed(False);
116   if Collection is TConditionItems then
117   begin
118     if TConditionItems(Collection).FConditionUI <> nil then
119     begin
120       nIndex := TConditionItems(Collection).FConditionUI.GetCurConditionIndex;
121       if nIndex >= 0 then
122         TConditionItems(Collection).FConditionUI.ConditionGrid.DataController.Values[nIndex, 1] := FConditionValue;
123     end;
124   end;
125 end;
126
127 procedure TConditionItem.SetConditionValueType(
128   const Value: TConditionItemDataType);
129 begin
130   FConditionValueType := Value;
131 //  Changed(False);
132 end;
133
134 procedure TConditionItem.SetIndex(Value: Integer);
135 begin
136   inherited SetIndex(Value);
137 { 这里不需要处理,SetIndex会触发Changed,从而触发容器的Update。Update已经有控制表格的处理逻辑。
138   if Collection is TConditionItems then
139   begin
140     if TConditionItems(Collection).FConditionUI <> nil then
141       TConditionItems(Collection).FConditionUI.BuildConditionGridByItems;
142   end;}
143 end;
144
145 procedure TConditionItem.SetItems(const Value: TStrings);
146 begin
147   FItems.Assign(Value);
148 end;
 
在SetConditionActionIndex方法中本来做一个越界的检测,但是实际调试中发现,property ConditionActionIndex : TConditionActionIndex的Set方法总是先于TConditionUI类的property ConditionController : TConditionController的Set方法,导致判断代码中通过TConditionItems(Collection).FConditionUI.ConditionController获取TConditionController的时候为nil,我对组件的属性的设置的先后机制还不是很了解,只好暂时作罢。
  查询条件项容器定义TConditionItems
 
 1   TConditionItems = class(TCollection)
 2   private
 3     FConditionUI: TConditionUI;
 4     function GetItems(Index: Integer): TConditionItem;
 5     procedure SetItems(Index: Integer; const Value: TConditionItem);
 6     function GetConditionUI: TConditionUI;
 7   protected
 8     function GetOwner: TPersistent; override;
 9     procedure Update(Item: TCollectionItem); override;
10     { TCollection遍历时是按照ID来进行的,也就是List中的存储位置进行。实际上,我们需要的是按照我们自己的排列顺序。}
11     function FindItemIndex(index: Integer): TConditionItem;
12     function FindItemName(AConditionName : string) : TConditionItem;
13   public
14     constructor Create(AConditionUI: TConditionUI; ItemClass: TItemClass);
15     function Add: TConditionItem;
16     property Items[Index: Integer]: TConditionItem read GetItems write SetItems;
17     property ConditionUI : TConditionUI read GetConditionUI;
18   end;
 
  查询条件项容器实现TConditionItems
 
 1 { TConditionItems }
 2
 3 function TConditionItems.Add: TConditionItem;
 4 begin
 5   Result := TConditionItem(inherited Add);
 6 end;
 7
 8 constructor TConditionItems.Create(AConditionUI: TConditionUI;
 9   ItemClass: TItemClass);
10 begin
11   inherited Create(ItemClass);
12   FConditionUI := AConditionUI;
13 end;
14
15 function TConditionItems.FindItemIndex(index: Integer): TConditionItem;
16 var
17   i : Integer;
18 begin
19   Result := nil;
20   for i := 0 to Count - 1 do
21   begin
22     if Items[i].Index = index then
23     begin
24       Result := Items[i];
25       Break;
26     end;
27   end;
28 end;
29
30 function TConditionItems.FindItemName(
31   AConditionName: string): TConditionItem;
32 var
33   i : Integer;
34 begin
35   Result := nil;
36   for i := 0 to Count - 1 do
37   begin
38     if UpperCase(Items[i].ConditionName) = UpperCase(AConditionName) then
39     begin
40       Result := Items[i];
41       Break;
42     end;
43   end;
44 end;
45
46 function TConditionItems.GetConditionUI: TConditionUI;
47 begin
48   Result := FConditionUI;
49 end;
50
51 function TConditionItems.GetItems(Index: Integer): TConditionItem;
52 begin
53   Result := TConditionItem(inherited Items[Index]);
54 end;
55
56 function TConditionItems.GetOwner: TPersistent;
57 begin
58   Result := FConditionUI;
59 end;
60
61 procedure TConditionItems.SetItems(Index: Integer;
62   const Value: TConditionItem);
63 begin
64   Items[Index].Assign(Value);
65 end;
66
67 procedure TConditionItems.Update(Item: TCollectionItem);
68 begin
69   if (FConditionUI.ConditionGrid = nil) or (csLoading in FConditionUI.ConditionGrid.ComponentState) then Exit;
70   if Item = nil then
71   begin
72   end
73   else
74   begin 
75   end;
76   FConditionUI.BuildConditionGridByItems;
77 end;
 
  查询条件表格显示控制类TConditionUI
 
 1   TConditionUI = class(TComponent)
 2   private
 3     FConditionGrid: TcxGridTableView;
 4     FConditionItems: TConditionItems;
 5     FSelectedStyle: TcxStyle;
 6     FNormalStyle: TcxStyle;
 7     FConditionController: TConditionController;
 8     procedure SetConditionGrid(const Value: TcxGridTableView);
 9     procedure SetConditionItems(const Value: TConditionItems);
10     procedure SetNormalStyle(const Value: TcxStyle);
11     procedure SetSelectedStyle(const Value: TcxStyle);
12     procedure SetConditionController(const Value: TConditionController);
13     function GetCurConditionIndex: Integer;
14     { Private declarations }
15   protected
16     { Protected declarations }
17     function CreateConditionItems : TConditionItems; dynamic;
18     procedure BuildConditionGridByItems; virtual;
19     procedure CustomDrawIndicatorCell(
20       Sender: TcxGridTableView; ACanvas: TcxCanvas;
21       AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean);
22     procedure FocusedRecordChanged(
23           Sender: TcxCustomGridTableView; APrevFocusedRecord,
24           AFocusedRecord: TcxCustomGridRecord;
25           ANewItemRecordFocusingChanged: Boolean);
26   public
27     { Public declarations }
28     constructor Create(AOwner : TComponent); override;
29     destructor Destroy; override;
30     { 根据条件名称获取条件值}
31     function GetConditionValue(AConditionName : string) : Variant;
32     property CurConditionIndex : Integer read GetCurConditionIndex;
33   published
34     { Published declarations }
35      property ConditionGrid :  TcxGridTableView read FConditionGrid write SetConditionGrid;
36      property ConditionItems : TConditionItems read FConditionItems write SetConditionItems;
37      property SelectedStyle : TcxStyle read FSelectedStyle write SetSelectedStyle;
38      property NormalStyle : TcxStyle read FNormalStyle write SetNormalStyle;
39      property ConditionController : TConditionController read FConditionController write SetConditionController;
40   end;
 
  查询条件表格显示控制类实现TConditionUI
 
  1 { TConditionUI }
  2
  3 procedure TConditionUI.BuildConditionGridByItems;
  4 const
  5   AColumnName: array[0..2] of string = ('gd_SetConditionTJ', 'gd_SetConditionValue', 'gd_SetConditionNO');
  6   AColumnCaption: array[0..2] of string = ('查询条件', '条件值', '隐藏列');
  7 var
  8   i : integer;
  9   Column : TcxGridColumn;
 10 begin
 11   if FConditionGrid <> nil then
 12   begin
 13     with FConditionGrid do
 14     begin
 15       BeginUpdate;
 16       { 清空表格记录 }
 17       OptionsSelection.CellMultiSelect := true;
 18       DataController.ClearSelection;
 19       DataController.SelectAll;
 20       DataController.DeleteSelection;
 21       OptionsSelection.CellMultiSelect := False;
 22
 23       { 清空表格列 }
 24       for i := FConditionGrid.ColumnCount - 1 downto 0 do
 25       begin
 26         FConditionGrid.Columns[i].Free;
 27       end;
 28      
 29       { 创建表格列 }
 30       for i := 0 to 2 do
 31       begin
 32         Column := FConditionGrid.CreateColumn;
 33         Column.Name := AColumnName[i];
 34         Column.Caption := AColumnCaption[i];
 35         if i = 0 then
 36           Column.Options.Focusing := False
 37         else
 38         if i = 2 then
 39           Column.Visible := False;
 40       end;
 41       { 创建表格行 }
 42       for i := 0 to FConditionItems.Count -1 do
 43       begin
 44         DataController.AppendRecord;
 45         DataController.Values[i, 0] := TConditionItem(FConditionItems.FindItemIndex(i)).ConditionLabel;
 46         DataController.Values[i, 2] := IntToStr(TConditionItem(FConditionItems.FindItemIndex(i)).Index);
 47         DataController.Values[i, 1] := '2012-01-01';
 48       end;
 49
 50       EndUpdate;
 51     end;
 52   end;
 53 end;
 54
 55 constructor TConditionUI.Create(AOwner: TComponent);
 56 begin
 57   inherited Create(AOwner);
 58   FSelectedStyle := TcxStyle.Create(Self);
 59   FSelectedStyle.Name := 'cxSelectedStyle';
 60   FSelectedStyle.Font.Name := 'MS Sans Serif';
 61   FSelectedStyle.Font.Size := 8;
 62   FSelectedStyle.Color := $00FED2B3;
 63   FSelectedStyle.AssignedValues := [svColor, svTextColor];
 64
 65   FNormalStyle := TcxStyle.Create(Self);
 66   FNormalStyle.Name := 'cxNormalStyle';
 67   FNormalStyle.Font.Name := '宋体';
 68   FNormalStyle.Font.Size := 9;
 69   FNormalStyle.Color := $00FED2B3;
 70   FNormalStyle.AssignedValues := [svColor, svFont, svTextColor];
 71  
 72   FConditionItems := CreateConditionItems;
 73 end;
 74
 75 function TConditionUI.CreateConditionItems: TConditionItems;
 76 begin
 77   Result := TConditionItems.Create(Self, TConditionItem);
 78 end;
 79
 80 procedure TConditionUI.CustomDrawIndicatorCell(Sender: TcxGridTableView;
 81   ACanvas: TcxCanvas; AViewInfo: TcxCustomGridIndicatorItemViewInfo;
 82   var ADone: Boolean);
 83 var
 84   vstr: string;
 85   vIndicatorViewInfo: TcxGridIndicatorRowItemViewInfo;
 86   vTextRect: TRect;
 87   vStyle: TcxStyle;
 88 begin
 89 { 行号设置 }
 90   if not (AViewInfo is TcxGridIndicatorRowItemViewInfo) then
 91     Exit;
 92
 93   vTextRect := AViewInfo.ContentBounds;
 94   vIndicatorViewInfo := AViewInfo as TcxGridIndicatorRowItemViewInfo;
 95   InflateRect(vTextRect, -2, -1);
 96
 97   vstr := IntToStr(vIndicatorViewInfo.GridRecord.Index + 1);
 98
 99   if vIndicatorViewInfo.GridRecord.Selected then
100     vStyle := FSelectedStyle
101   else
102     vStyle := FNormalStyle;
103   Sender.LookAndFeelPainter.DrawHeader(ACanvas, AViewInfo.ContentBounds,
104     vTextRect, [], cxBordersAll, cxbsNormal, taCenter, vaCenter,
105     False, False, vstr,
106     vStyle.Font, vStyle.TextColor, vStyle.Color);
107
108   ADone := True;
109 end;
110
111 procedure TConditionUI.FocusedRecordChanged(
112   Sender: TcxCustomGridTableView; APrevFocusedRecord,
113   AFocusedRecord: TcxCustomGridRecord;
114   ANewItemRecordFocusingChanged: Boolean);
115 var
116   AConditionItem : TConditionItem;
117   AConditionEditType : TConditionEditType;
118 begin
119   {在这个事件里面,处理不同的查询条件类型,编辑的模式的切换}
120   if AFocusedRecord <> nil then
121   begin
122     AConditionItem := FConditionItems.FindItemIndex(AFocusedRecord.Index);
123     //ShowMessage(AConditionItem.ConditionLabel);
124     FConditionController.CurCondtionItemIndex := AConditionItem.Index;
125     AConditionEditType := AConditionItem.ConditionEditType;
126     if AConditionEditType in [cetEdit, cetButtonEdit] then
127     begin
128       FConditionGrid.FindItemByName('gd_SetConditionValue').PropertiesClass:= TcxButtonEditProperties;
129       if FConditionController <> nil then
130       begin
131         (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
132               TcxButtonEditProperties).OnButtonClick := FConditionController.PropertiesButtonClickEvent;
133         (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
134               TcxButtonEditProperties).OnValidate := FConditionController.PropertiesValidate;
135       end;
136       (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
137         TcxButtonEditProperties).Buttons.Items[0].Visible := AConditionEditType = cetButtonEdit;
138     end   
139     else
140     if AConditionEditType = cetComboBox then
141     begin
142       FConditionGrid.FindItemByName('gd_SetConditionValue').PropertiesClass:= TcxComboBoxProperties;
143       (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
144       TcxComboBoxProperties).ImmediatePost := True;
145       (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
146         TcxComboBoxProperties).DropDownListStyle := lsFixedList;
147       (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
148       TcxComboBoxProperties).OnCloseUp := FConditionController.PropertiesCloseUp;
149       (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
150             TcxComboBoxProperties).OnValidate := FConditionController.PropertiesValidate;
151
152       with (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
153         TcxComboBoxProperties).Items do
154       begin
155         (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
156         TcxComboBoxProperties).Items.Assign(AConditionItem.Items);
157       end
158     end
159     else
160 //    if AConditionEditType = cetDatePicker then
161 //    begin
162 //      FConditionGrid.FindItemByName('gd_SetConditionValue').PropertiesClass:= TcxDateEditProperties;
163 //      if FConditionController <> nil then
164 //      begin
165 //        (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
166 //              TcxDateEditProperties).OnChange := FConditionController.PropertiesChange;
167 //        (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
168 //              TcxDateEditProperties).OnValidate := FConditionController.PropertiesValidate;
169 //      end;
170 //    end   
171 //    else
172     begin
173       FConditionGrid.FindItemByName('gd_SetConditionValue').PropertiesClass:= TcxButtonEditProperties;
174       (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
175             TcxButtonEditProperties).OnButtonClick := FConditionController.PropertiesButtonClickEvent;
176       (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
177             TcxButtonEditProperties).OnValidate := FConditionController.PropertiesValidate;
178       (FConditionGrid.FindItemByName('gd_SetConditionValue').Properties as
179         TcxButtonEditProperties).Buttons.Items[0].Visible := true;
180     end;
181   end;
182 end;
183
184 destructor TConditionUI.Destroy;
185 begin
186   FConditionItems.Free;
187   FConditionItems := nil;
188
189   inherited;
190 end;
191
192 function TConditionUI.GetConditionValue(AConditionName: string): Variant;
193 var
194   AConditionItem : TConditionItem;
195 begin
196   Result := EmptyParam;
197   AConditionItem := FConditionItems.FindItemName(AConditionName);
198   if AConditionItem <> nil then
199   begin
200     Result := AConditionItem.ConditionValue;
201   end;
202 end;
203
204 procedure TConditionUI.SetConditionGrid(const Value: TcxGridTableView);
205 begin
206   FConditionGrid := Value;
207   if FConditionGrid <> nil then
208   begin
209     {处理行号}
210     FConditionGrid.OptionsView.Indicator := True;
211     FConditionGrid.OptionsView.IndicatorWidth := 24;
212     FConditionGrid.OnCustomDrawIndicatorCell := CustomDrawIndicatorCell;
213     {隐藏拖动分组的区域}
214     FConditionGrid.OptionsView.GroupByBox := False;
215     FConditionGrid.OptionsView.ColumnAutoWidth := True;
216     {指定激活行改变事件}
217     FConditionGrid.OnFocusedRecordChanged := FocusedRecordChanged;
218     FConditionGrid.OptionsCustomize.ColumnFiltering := False;
219     FConditionGrid.OptionsCustomize.ColumnMoving := False;
220     FConditionGrid.OptionsCustomize.ColumnSorting := False;
221   end;
222 end;
223
224 procedure TConditionUI.SetConditionItems(const Value: TConditionItems);
225 begin
226   FConditionItems.Assign(Value);
227 end;
228
229 procedure TConditionUI.SetNormalStyle(const Value: TcxStyle);
230 begin
231   FNormalStyle.Assign(Value);
232 end;
233
234 procedure TConditionUI.SetSelectedStyle(const Value: TcxStyle);
235 begin
236   FSelectedStyle.Assign(Value);
237 end;
238
239 procedure TConditionUI.SetConditionController(
240   const Value: TConditionController);
241 begin
242   FConditionController := Value;
243   Value.UIComponent := Self;
244 end;
245
246 function TConditionUI.GetCurConditionIndex: Integer;
247 begin
248   Result := FConditionGrid.DataController.FocusedRowIndex;
249 end;
 
本来日期类型的处理是打算用CX自身的TcxDateEditProperties来实现的,结果发现其事件的机制有点不好控制,所以还是采取自定义的方式来解决。反正现行项目也有专门的日期选择模块可以重用。
  查询条件逻辑控制类ConditionController
 
  1 unit ConditionController;
  2
  3 interface
  4
  5 uses
  6   SysUtils, Classes, Controls, Dialogs, ConditionConst, cxGridCustomTableView;
  7
  8 type
  9   TConditionController = class;
 10  
 11   { 查询条件项获取方式 }
 12   TConditionAction = class(TCollectionItem)
 13   private
 14     FActionName: string;
 15     FOnExecute: TNotifyEvent;
 16     procedure SetActionName(const Value: string);
 17     procedure SetOnExecute(const Value: TNotifyEvent);
 18   public
 19     constructor Create(Collection: TCollection); override;
 20     destructor Destroy; override;
 21     procedure Assign(Source: TPersistent); override;
 22   published
 23     { Action名称 }
 24     property ActionName : string read FActionName write SetActionName;
 25     property OnExecute : TNotifyEvent read FOnExecute write SetOnExecute;
 26   end;
 27
 28   TItemClass = class of TConditionAction;
 29
 30   { 查询条件项Action列表 }
 31   TConditionActions = class(TCollection)
 32   private
 33     FConditionController: TConditionController;
 34     function GetItems(Index: Integer): TConditionAction;
 35     procedure SetItems(Index: Integer; const Value: TConditionAction);
 36   protected
 37     function GetOwner: TPersistent; override;
 38   public
 39     constructor Create(AConditionController: TConditionController; ItemClass: TItemClass);
 40     function Add: TConditionAction;
 41     property Items[Index: Integer]: TConditionAction read GetItems write SetItems;
 42   end;
 43
 44   { 查询条件控制类 }
 45   TConditionController = class(TComponent)
 46   private
 47     FConditionActions: TConditionActions;
 48     FCurCondtionItemIndex: Integer;
 49     FUIComponent: TComponent;
 50     procedure SetConditionActions(const Value: TConditionActions);
 51     procedure SetCurCondtionItemIndex(const Value: Integer);
 52     procedure SetUIComponent(const Value: TComponent);
 53     { Private declarations }
 54   protected
 55     { Protected declarations }
 56     function CreateConditionActions : TConditionActions; dynamic;
 57   public
 58     { Public declarations }
 59     constructor Create(AOwner : TComponent); override;
 60     destructor Destroy; override;
 61
 62     (* 单击编辑框按钮事件 *)
 63     procedure PropertiesButtonClickEvent(Sender: TObject; AButtonIndex: Integer);
 64     (* 编辑值合法性检测事件 *)
 65     procedure PropertiesValidate(Sender: TObject;
 66         var DisplayValue: Variant; var ErrorText: TCaption;
 67         var Error: Boolean);
 68     (* 下拉框菜单关闭事件 *)
 69     procedure PropertiesCloseUp(Sender: TObject);
 70     (* 日期控件改变事件 *)
 71     procedure PropertiesChange(Sender: TObject);
 72     (* TableView的Edit事件 *)
 73     procedure EditChanged(Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem);
 74     property CurCondtionItemIndex : Integer read FCurCondtionItemIndex write SetCurCondtionItemIndex;
 75     property UIComponent : TComponent read FUIComponent write SetUIComponent;
 76   published
 77     { Published declarations }
 78     property ConditionActions : TConditionActions read FConditionActions write SetConditionActions;
 79   end;
 80
 81 procedure Register;
 82
 83
 84 implementation
 85
 86 uses
 87   ConditionUI;
 88
 89   procedure Register;
 90 begin
 91   RegisterComponents('Samples', [TConditionController]);
 92 end;
 93
 94 { TConditionAction }
 95
 96 procedure TConditionAction.Assign(Source: TPersistent);
 97 begin
 98   inherited;
 99
100 end;
101
102 constructor TConditionAction.Create(Collection: TCollection);
103 begin
104   inherited;
105   FActionName := Self.ClassName+IntToStr(Collection.Count);
106 end;
107
108 destructor TConditionAction.Destroy;
109 begin
110
111   inherited;
112 end;
113
114 procedure TConditionAction.SetActionName(const Value: string);
115 begin
116   FActionName := Value;
117 end;
118
119 procedure TConditionAction.SetOnExecute(const Value: TNotifyEvent);
120 begin
121   FOnExecute := Value;
122 end;
123
124 { TConditionActions }
125
126 function TConditionActions.Add: TConditionAction;
127 begin
128   Result := TConditionAction(inherited Add);
129 end;
130
131 constructor TConditionActions.Create(
132   AConditionController: TConditionController; ItemClass: TItemClass);
133 begin
134   inherited Create(ItemClass);
135   FConditionController := AConditionController;
136 end;
137
138 function TConditionActions.GetItems(Index: Integer): TConditionAction;
139 begin
140   Result := TConditionAction(inherited Items[Index]);
141 end;
142
143 function TConditionActions.GetOwner: TPersistent;
144 begin
145   Result := FConditionController;
146 end;
147
148 procedure TConditionActions.SetItems(Index: Integer;
149   const Value: TConditionAction);
150 begin
151   Items[Index].Assign(Value);
152 end;
153
154 { TConditionController }
155
156 constructor TConditionController.Create(AOwner: TComponent);
157 begin
158   inherited;
159   FConditionActions := CreateConditionActions;
160   FCurCondtionItemIndex := 0;
161 end;
162
163 function TConditionController.CreateConditionActions: TConditionActions;
164 begin
165   Result := TConditionActions.Create(Self, TConditionAction);
166 end;
167
168 destructor TConditionController.Destroy;
169 begin
170   FConditionActions.Free;
171   FConditionActions := nil;
172
173   inherited;
174 end;
175
176 procedure TConditionController.EditChanged(Sender: TcxCustomGridTableView;
177   AItem: TcxCustomGridTableItem);
178 var
179   AConditionItem : TConditionItem;
180 begin
181   //AConditionItem := TConditionUI(FUIComponent).ConditionItems.Items[FCurCondtionItemIndex];
182
183   //AConditionItem.ConditionValue := TConditionUI(FUIComponent).ConditionItems.ConditionUI.ConditionGrid.DataController.Values[FCurCondtionItemIndex, 1];
184
185   ShowMessage(AConditionItem.ConditionValue);
186 end;
187
188 procedure TConditionController.PropertiesButtonClickEvent(Sender: TObject;
189   AButtonIndex: Integer);
190 var
191   AConditionItem : TConditionItem;
192   AConditionAction : TConditionAction;
193 begin
194   AConditionItem := TConditionUI(FUIComponent).ConditionItems.Items[FCurCondtionItemIndex];
195   AConditionAction := FConditionActions.Items[AConditionItem.ConditionActionIndex];
196  
197   if (AConditionAction <> nil) then
198   begin
199     if Assigned(AConditionAction.FOnExecute) then
200     begin
201       AConditionAction.FOnExecute(AConditionItem);
202     end;
203   end;
204 end;
205
206 procedure TConditionController.PropertiesChange(Sender: TObject);
207 var
208   AConditionItem : TConditionItem;
209   AConditionAction : TConditionAction;
210 begin
211   AConditionItem := TConditionUI(FUIComponent).ConditionItems.Items[FCurCondtionItemIndex];
212   AConditionAction := FConditionActions.Items[AConditionItem.ConditionActionIndex];
213  
214   if (AConditionAction <> nil) then
215   begin
216     if Assigned(AConditionAction.FOnExecute) then
217     begin
218       AConditionAction.FOnExecute(AConditionItem);
219     end;
220   end;
221 end;
222
223 procedure TConditionController.PropertiesCloseUp(Sender: TObject);
224 var
225   AConditionItem : TConditionItem;
226   AConditionAction : TConditionAction;
227 begin
228   AConditionItem := TConditionUI(FUIComponent).ConditionItems.Items[FCurCondtionItemIndex];
229   AConditionAction := FConditionActions.Items[AConditionItem.ConditionActionIndex];
230  
231   if (AConditionAction <> nil) then
232   begin
233     if Assigned(AConditionAction.FOnExecute) then
234     begin
235       AConditionAction.FOnExecute(AConditionItem);
236     end;
237   end;
238 end;
239
240 procedure TConditionController.PropertiesValidate(Sender: TObject;
241   var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
242 begin
243
244 end;
245
246 procedure TConditionController.SetConditionActions(
247   const Value: TConditionActions);
248 begin
249   FConditionActions := Value;
250 end;
251
252 procedure TConditionController.SetCurCondtionItemIndex(
253   const Value: Integer);
254 begin
255   FCurCondtionItemIndex := Value;
256 end;
257
258 procedure TConditionController.SetUIComponent(const Value: TComponent);
259 begin
260   if Value is TConditionUI then
261     FUIComponent := Value
262   else
263     raise Exception.Create('UIComponent属性只接受TConditionUI类型的对象。');
264 end;
265
266 end.
 
里面有一些冗余的事件代码,主要是为了测试不同编辑器下不同事件的效果和触发时机对系统业务流程的影响。

 


摘自 编码笔记

图片内容