-
您可以应用Tag 属性来存储字段索引,您将使用该索引在过滤器生成中获取字段名称。
-
要存储每个过滤器的值,您可以使用 Form 的私有 TDictionary 字段。
uses
{ here all other modules }, System.Generics.Collections;
type
TForm1 = class(TForm)
{ here all components declaration }
strict private
Filters: TDictionary<Integer, string>;
我们应该在 App 启动时初始化 Filters。您可以在执行初始设置的任何地方执行此操作(OnCreate、OnShow 或表单的任何其他事件;initialization 部分等)。我将使用OnCreate 事件处理程序作为示例。您可以通过双击 OnCreate 附近的空单元格在 Object Inspector 的 Event 选项卡中生成空处理程序并将其自动附加到 Form:
所以现在我们应该在这个事件处理程序中初始化Filters:
procedure TForm1.FormCreate(Sender: TObject);
begin
{ here all your previous setup (if exist) }
Filters := TDictionary<Integer, string>.Create;
end;
如果需要,您还应该在此处初始化过滤器的默认值。如果您在 Object Inspector 中设置 Text 的默认值并希望它们用于过滤查询,则必须这样做,因为这样的值不会自动保存到我们的 Filters 中没有触发任何OnChange 事件。
-
现在让我们为TComboBox 定义通用OnChange 事件处理程序,它将值存储到Filters:
首先,我们应该将事件处理程序的签名添加到 Form 类的 public 部分。由于 public 是类中的默认访问修饰符,您可以在组件列表或其他处理程序下添加您的函数(如果存在):
type
TForm1 = class(TForm)
{ here all components declaration }
procedure ComboBoxChange(Sender: TObject);
然后您可以将光标指向此声明并按 ShiftCtrlC 这应该让 IDE 生成如下所示的空函数:
procedure TForm1.ComboBoxChange(Sender: TObject);
begin
end;
我们已经为每个 ComboBox 定义了唯一的 Tag 值,因此我们可以将其用作键。事件处理程序非常简单:
procedure TForm1.ComboBoxChange(Sender: TObject);
begin
with Sender as TComboBox do
Filters.AddOrSetValue(Tag, Text);
end;
最后,您应该将此事件处理程序添加到每个 ComboBox。复制函数名称并将其粘贴到 Object Inspector 的 Events 选项卡中 OnChange 附近的空单元格中,对您要用于过滤的每个 ComboBox 重复此操作:
-
最后一步是编写函数,该函数将生成过滤查询并更新我们的事件处理程序以使用 ADOTable。让我们在 Form 类的私有部分定义我们的函数:
type
TForm1 = class(TForm)
{ here all components declaration }
strict private
Filters: TDictionary<Integer, string>;
function GetFilterQuery(SkipEmptyValues: Boolean = False): string;
按 ShiftCtrlC 生成函数。在函数中,我们将使用for ... in 循环遍历Filters,使用string.Format 为Filters 和string.Join 的每个元素创建过滤器字符串以加入所有创建的字符串(我使用了TList<string>作为临时数据容器):
function TForm1.GetFilterQuery(SkipEmptyValues: Boolean): string;
var
Pair: TPair<Integer, string>;
Conditions: TList<string>;
begin
result := string.Empty;
Conditions := TList<string>.Create;
for Pair in Filters do
with Pair do
if (not SkipEmptyValues) or (not Value.IsEmpty) then
Conditions.Add(string.Format('field%d=%s', [Key, Value.QuotedString]));
if Conditions.Count > 0 then
result := string.Join(' and ', Conditions.ToArray);
Conditions.Free;
end;
最后,我们应该在 OnChange 事件处理程序中调用这个函数:
procedure TForm1.ComboBoxChange(Sender: TObject);
var
Query: string;
begin
with Sender as TComboBox do
Filters.AddOrSetValue(Tag, Text);
Query := GetFilterQuery(True);
if not Query.IsEmpty then
begin
ADOTable1.Filtered := False;
ADOTable1.Filter := Query;
ADOTable1.Filtered := True;
end;
end;