 Lazarus
		Lazarus
		| ListView и разбиение данных на порции (ч.2) | 27.07.2009 Leonardo M. Rame | 
В предыдущей части статьи я написал о методе разбиения данных на порции, которые отображаются в ListView. Теперь я хочу расширить метод, заменяя TDataSet на TCollection.
TCollection - контейнер, где сохраняются объекты только одного типа. В отличие от других контейнеров, таких как TList и TObjectList, которые могут содержать любой вид - указателя, в случае TList, и разнородных объектов в случаеTObjectList, в TCollection могут использоваться только объекты определенного класса.
Чтобы создать коллекцию Песен, мы должны унаследовать класс из TCollectionItem, назовём например TSong и другой класс от TCollection, например TSongs, следующим образом:
TSong = class(TCollectionItem) private FId: string; FSolist: string; FSongName: string; public property Id: string read FId write FId; property Solist: string read FSolist write FSolist; property SongName: string read FSongName write FSongName; end; TSongs = class(TCollection) private function GetItem (AIndex: Integer): TSong; public function Add: TSong; property Items[AIndex: Integer]: TSong read GetItem; default; end;
Теперь определяем методы Add и GetItem:
function TSongs.GetItem (AIndex: Integer): TCustomer; begin Result: = TSongs(inherited GetItem(AIndex)); end; function TSongs.Add: TCustomer; begin Result: = TSongs(inherited Add); end;
Сохраните вышеупомянутый код в модуле c названем songs.pas, затем создайте новое приложение и добавьте названте недавно созданного модуля в раздел "Uses" основной формы, затем добавьте свойство FSongs: TSongs; в private секцию формы:
type
TForm1 = class(TForm)
private
  FSongs: TSongs;
public
  {Public declarations}
end;
Теперь измените методы OnCreate и OnDestroy основной формы, чтобы создавать и удалять коллекцию:
procedure TForm1.FormCreate(Sender: TObject); begin FSongs: = TSongs.Create(TSong); end; procedure TForm1.FormDestroy(Sender: TObject); begin FSongs.Free; end;
Итак, следующи шагом заполняем коллекцию данными.
Поместите компоненты обеспечения связи с базой данных так же, как я объяснял в предыдущей части статьи, в DataModule или в основной форме (т.к. это - только пример).
Далее доработаем метод FormCreate вот так:
procedure TForm1. FormCreate (Sender: TObject);
begin
  //Создаем коллекцию
  FSongs:=TSongs.Create(TSong);
  //Определяем общее количество записей
  SQLQuery1.SQL.Clear;
  SQLQuery1.SQL.Text:='SELECT COUNT(*) FROM rus';
  SQLQuery1.Open;
  FAllRecords:=SQLQuery1.Fields[0].AsInteger;
  SQLQuery1.Close;
  //Основной запрос
  SQLQuery1.SQL.Clear;
  SQLQuery1.SQL.Add('SELECT rus.id, sol.name, rus.name');
  SQLQuery1.SQL.Add('FROM rus INNER JOIN sol');
  SQLQuery1.SQL.Add('ON rus.sol_id=sol.id');
  SQLQuery1.SQL.Add('ORDER BY sol.name, rus.name');
  SQLQuery1.SQL.Add('LIMIT '+IntToStr(cPageSize)+' OFFSET :n');
  SQLQuery1.Params[0].AsInteger:=0;
  SQLQuery1.Open;
  GetCurrentPage(dqCurr);
end;
Теперь, чтобы заполнить наш TCollection данными из базы данных, измените метод GetCurrentPage таким образом:
procedure TForm1.GetCurrentPage(Dir: TDirQuery);
Var
  i: Integer;
begin
  //В зависимости от параметра процедуры определяем с какого номера записи проводить выборку
  Case Dir of
    dqPrev: If SQLQuery1.Params[0].AsInteger>=cPageSize Then
              SQLQuery1.Params[0].AsInteger:=SQLQuery1.Params[0].AsInteger-cPageSize;
    dqNext: If SQLQuery1.Params[0].AsInteger<=FAllRecords-cPageSize Then
              SQLQuery1.Params[0].AsInteger:=SQLQuery1.Params[0].AsInteger+cPageSize;
  End;
  SQLQuery1.Close;
  SQLQuery1.Open;
  //Заполняем коллекцию
  FSongs.Clear;
  While not SQLQuery1.Eof Do
  Begin
    With FSongs.Add Do
    Begin
      Id := SQLQuery1.Fields[0].AsString;
      Solist := SQLQuery1.Fields[1].AsString;
      SongName := SQLQuery1.Fields[2].AsString;
    End;
    SQLQuery1.Next;
 End;
  //Заполняем полученой порцией данных компонент отображения
  ListView1.Items.Clear;
  For i:=0 To FSongs.Count-1 Do
  Begin
    ListView1.Items.Add;
    ListView1.Items[i].Caption:=FSongs[i].Id;
    ListView1.Items[i].SubItems.Add(FSongs[i].Solist);
    ListView1.Items[i].SubItems.Add(FSongs[i].SongName);
  End;
end;
Последний шаг - поместите TListView на форму, установите ее свойства как показано в предыдущей части статьи.
Вот и все.
Пример 2: listview2.s3.7z
| FPC | 3.2.2 | release | 
| Lazarus | 3.2 | release | 
| MSE | 5.10.0 | release | 
| fpGUI | 1.4.1 | release |