截至今天,查询条件的封装第一阶段的工作基本完成了。在之前的基础上做了一些调整,由于D7与XE/XE2的差异,某些思路也做了调整。查询条件项的驱动控制由于是使用TCollection和TCollectionItem来实现的,所以不能作为查询条件项的属性来进行选择(应该是只有继承自TComponent的组件才可以作为属性的选择对象),取而代之的是采用Index的方式来进行绑定,这个我觉得是设计上的一个缺陷,并没有完全符合我最初的设想,在使用上不够简便直观。如果是在XE2下可以有更好的选择,可以用TCustomAttribute加反射机制来实现持久化配置数据的动态绑定。
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.
这里对预置的标准查询条件项采取了数组定义的方式,只是为了验证技术环节是否通畅,这里最终应该考虑和数据的绑定。
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;
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,我对组件的属性的设置的先后机制还不是很了解,只好暂时作罢。
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;
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;
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;
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来实现的,结果发现其事件的机制有点不好控制,所以还是采取自定义的方式来解决。反正现行项目也有专门的日期选择模块可以重用。
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.
里面有一些冗余的事件代码,主要是为了测试不同编辑器下不同事件的效果和触发时机对系统业务流程的影响。