截至今天,查詢條件的封裝第一階段的工作基本完成了。在之前的基礎上做了一些調整,由於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.
裡面有一些冗余的事件代碼,主要是為了測試不同編輯器下不同事件的效果和觸發時機對系統業務流程的影響。
摘自 編碼筆記