Шрифт:
'(ASC) ') ;
var aField: string;
aFieldlndex: integer;
begin
aField := Column.FieldName;
aFieldlndex := SortFields.IndexOf(aField) ;
if aFieldlndex = -1 then begin
SortFields.Add(aField);
SortFields.Ascending[SortFields.Count - 1] := true;
Column.Field.Display-Label := Column. Field.FieldName + OrderStr[true];
end
else begin
SortFields.Ascending[aFieldlndex] := not
SortFields.Ascending[aFieldlndex];
Column.Field.Display-Label := Column.Field.FieldName +
OrderStr[SortFields.Ascending[aFieldlndex]];
end;
ReSort;
end;
Смысл обработчика состоит в следующем: при нажатии пользователем на заголовок мы проверяем, есть ли данное поле в нашем списке сортировки. Если нет, то мы добавляем его и формируем новый заголовок для колонки, который теперь будет состоять из названия поля и порядка сортировки (ASC) или (DESC). Если же поле уже было включено в сортировку, то мы лишь меняем порядок сортировки. В обоих случаях мы должны вызвать процедуру ReSort, описанную ниже:
procedure TMainForm.ReSort;
var Orders: array of boolean;
Index: Integer;
begin
if SortFields.Count = 0 then begin MainDS.CloseOpen(false);
exit;
end;
SetLength(Orders, SortFields.Count);
for Index := 0 to pred(SortFields.Count) do
Orders[Index] := SortFields.Ascending[Index];
MainDS.DoSortEx(SortFields, Orders);
end;
Данная процедура формирует списки для метода DoSortEx на основе списка SortFields и пересортировывает записи. В случае, если наш список сортировки пустой, мы должны вернуться к "стандартному" порядку записей. Для этого вызывается метод CloseOpen.
Параметр False означает, что мы не хотим автоматически получать сразу все записи от сервера.
Если наш список полей не пустой, то мы должны сформировать массив Orders. Это делается, как видно, достаточно легко. Используя динамические массивы, мы сначала задаем длину Orders равной количеству полей в списке SortFields, а потом последовательно заполняем Orders значениями свойства Ascending списка SortFields. Остается только вызвать метод DoSortEx - и сортировка б\дет выполнена.
Чтобы закрыть вопрос целиком, нам остается только предоставить пользователю возможность исключать поля из сортировки. Для этого мы положим на форму кнопку Button 1 (см. рис. 46, заголовок "Delete column from Sorting"):
procedure TMainForm.ButtonlClick(Sender: TObject);
var aField: string;
aFieldlndex: integer;
begin
aField := DBGridl.SelectedField.FieldName;
aFieldlndex := SortFields.IndexOf(aField);
if aFieldlndex <> -1 then begin
SortFields.Delete(aFieldlndex);
DBGridl.SelectedField.DisplayLabel := aField;
ReSort;
end;
end;
Пользователь выделяет поле, которое хочет удалить из сортировки, и нажимает на кнопку "Delete column from Sorting", после чего это поле удаляется из списка SortFields и производится пересортировка записей.
Локальная фильтрация
Аналогично локальной сортировке, которая оперирует только с данными в локальном буфере, мы можем также выбирать записи из уже полученных по какому-либо критерию, скрывая от пользователя "лишние" записи.
Рассмотрим локальную фильтрацию на примере приложения Filtering. Этот пример включен в стандартную поставку FIBPlus. В примере используется база данных FIBPlus_Example.gdb (рис. 2.68).
Эта база данных в виде backup-файла доступна на сайте http://www.fibplus.net/
Рис 2.68. Использование локальной фильтрации TpFIBDataSet
Совершенно очевиден код для подключения к базе данных. Список элементов компонента FieldsC: TComboBox заполняется названиями полей из таблицы BIOLIFE.
FilteringDS.SelectSQL: SELECT * FROM BIOLIFE
procedure TMainForm.btnConnectClickfSender: TObject);
var Index: Integer;
begin
with MainDB do begin
ConnectParams.UserName := edtUserName.Text;
ConnectParams.Password := edtPassword.Text;
DBName := edtDataBase.Text;
try
Open;
FilteredDS.Open;
FieldsC.Items.Clear;
for Index := 0 to pred(FilteredDS.FieldCount) do
FieldsC.Items.Add(FilteredDS.Fields[Index].FieldName);
except
MessageDlgt'Error of connection to a database!', mtError, [mbOk], 0) ;
Close;
end;
end;
end;
Пользователь может выбрать поле из списка FieldsC, указать в поле FilterE: TEdit строку для поиска и после нажатия на кнопку Button I ("Activate Filter"):