Se seznamy jsme se již v našem seriálu nejednou setkali. Dnes se zaměříme na komponentu, která nám umožňuje prohlížet seznamy a seznamové struktury a nabízí při tom neuvěřitelné množství voleb.
Se seznamy jsme se již v našem seriálu nejednou setkali. Dnes se ovšem zaměříme na komponentu, která nám umožňuje prohlížet seznamy a seznamové struktury a nabízí při tom neuvěřitelné množství voleb. Pomocí těchto voleb nastavujeme vlastnosti a chování výsledného vzhledu seznamu. V průběhu dnešní kapitoly vytvoříme společně (jako tradičně) ukázkovou aplikaci, ve které sami uvidíte, jak s komponentou pracovat.
Komponentu ListView jsme v našem seriálu ještě nezmínili (pokud mě paměť nemýlí), což je jistě škoda, neboť jde o poměrně komplexně vybavenou komponentu. Naleznete ji v paletě Win32, a jak již její název napovídá, slouží k prohlížení seznamu.
Pomocí ListView je možné prohlížet seznamy nejrůznějších položek (nikoliv tedy jen textových údajů). Položky (údaje) zobrazené v ListView mohou být zobrazeny ve sloupcích s případnými hlavičkami sloupců, mohou obsahovat „podpoložky“, mohou být zobrazeny horizontálně či vertikálně, mohou být znázorněny velkými nebo malými ikonami. ListView nabízí celou řadu možností, jak nastavit svou výslednou podobu a vlastnosti, a my se na některé z nich nyní podrobněji podíváme.
Vlastnosti komponenty ListView
Vlastnosti shrneme v následující tabulce:
Vlastnost |
Popis |
AllocBy |
Do této vlastnosti se nastavuje (maximální) počet položek (údajů), které budou v seznamu zobrazeny. Před tím, než do ListView „nasypete“ větší množství položek, je vhodné nastavit AllocBy. Delphi se tak může pokusit o alokaci souvislého bloku paměti pro všechny položky a nemusí alokovat úsek po úseku v průběhu postupného přidávání položek. |
BorderStyle |
Styl okraje komponenty, okraj může být buď standardní (bsSingle) nebo žádný (bsNone). |
CheckBoxes |
Logická hodnota říkající, má-li se u každé položky objevit zatrhávací políčko (CheckBox). |
Column |
Sloupce. V této vlastnosti se prostřednictvím indexu dostáváme ke všem sloupcům obsaženým v seznamu. Tato vlastnost má smysl jen pro hodnotu vlastnosti ViewStyle = vsReport. |
ColumnClick |
Logická hodnota udávající, jestli se má záhlaví sloupce chovat jako tlačítko. Je-li ColumnClick = True, je po klepnutí myší na záhlaví sloupce generována událost OnColumnClick. V opačném případě nevzniká tato událost nikdy. Aby mohlo býti na záhlaví sloupce klepnuto, musí toto záhlaví především být viditelné. Toho lze dosáhnout nastavením hodnoty vlastnosti ShowColumnHeaders na True a nastavením hodnoty vlastnosti ViewStyle na vsReport. |
Columns |
Typ této vlastnosti je TListColumns. Tato vlastnost popisuje sloupce seznamu. Slouží také k vytváření nových a likvidování existujících sloupců. Tato vlastnost (přesněji její třída TListColumns) má celou řadu vlastností a metod. |
GridLines |
Logická hodnota udávající, má-li se v seznamu zobrazovat mřížka oddělující jednotlivé položky. |
HideSelection |
Logická hodnota udávající, má-li být viditelný výběr položky i v případě, že ListView ztratí zaměření. Pokud hodnota HideSelection = True, po ztrátě zaměření nebude položka, jež byla předtím vybrána, nijak zvýrazněná. Pro HideSelection = False bude položka šedivě podbarvená. |
HotTrack |
Logická hodnota udávající, budou-li položky zvýrazněny (změní barvu) v okamžiku, kdy nad nimi přejede kurzor myši. |
IconOptions |
Typ této vlastnosti je TIconOptions a vlastnost udává, jakým způsobem budou rozmístěny ikony zobrazené v seznamu. Třída TIconOptions má celou řadu vlastností a metod. |
Items |
V této vlastnosti jsou obsaženy všechny položky zobrazené v ListView. |
LargeIcons |
Typ této vlastnosti je TImageList. Vlastnost obsahuje seznam ikon (obrázků), které se v seznamu zobrazí v případě, že hodnota ViewStyle je vsIcon. Příklad použití následuje v další podkapitole. |
MultiSelect |
Logická hodnota udávající, může-li uživatel vybrat (označit) zároveň více zobrazených položek. |
ReadOnly |
Logická hodnota udávající, může-li uživatel měnit jednotlivé položky. Může-li uživatel data měnit (ReadOnly = False), jsou generovány události OnEditing, resp. OnEdited v okamžiku, kdy uživatel začne, resp. dokončí editaci položky. |
RowSelect |
Logická hodnota udávající, může-li uživatel vybrat z komponenty ListView zároveň celou řádku. Pokud mu navíc chcete umožnit vybrat více (celých) řádek, nastavte MultiSelect = True. |
SelCount |
Udává počet aktuálně vybraných (nikoliv zobrazených) položek. Je-li SelCount = 1, můžete se k vybrané položce dostat jednoduše pomocí vlastnosti Selected. Je-li SelCount > 1, je třeba k detekci všech označených položek testovat jejich vlastnosti Selected. K tomu, aby bylo možno dosáhnouti stavu SelCount > 1, musí být samozřejmě povolen vícenásobný výběr: MultiSelect = True. Další popis viz vlastnost Selected. |
Selected*** |
Selected (typu TlistItem) obsahuje (první) označenou položku v seznamu. Pokud SelCount = 0 (tj. žádná označená položka), hodnota Selected = nil. Pokud SelCount > 1, je nutné testovat vlastnost Selected jednotlivých položek ze seznamu (viz např. metoda GetNextItem). Hodnotu Selected ovšem není nutné jen číst, jejím nastavením de facto položku v seznamu označíme. Nastavením Selected na nil provedeme odznačení všech položek. Důležitá poznámka k vlastnosti Selected je uvedena pod tabulkou. |
ShowColumnHeaders |
Logická hodnota udávající, mají-li se zobrazovat záhlaví sloupců. Záhlaví sloupce je panel obsahující titulek. Tento panel ve spolupráci s titulkem by měl jednoznačně identifikovat kategorii položek nacházejících se v příslušném sloupci. K přidávání a editaci sloupců se používá vlastnost Columns (a její metody). Aby bylo možné používat v ListView sloupce, musí být nastavena hodnota ViewStyle na vsReport. |
SmallImages |
Typ této vlastnosti je TImageList. Vlastnost obsahuje seznam ikon (obrázků), které se v seznamu zobrazí v případě, že hodnota ViewStyle není vsIcon. Příklad použití následuje v další podkapitole. |
SortType |
SortType udává, zda (a jak) mají být položky zobrazované v seznamu automaticky řazeny. Možné hodnoty: stNone (žádné třídění nebude použito), stData (položky jsou řazeny na základě hodnoty vlastnosti Data položek, vlastní algoritmus třídění, musí být uvedena v obsluze události OnCompare), stText (položky jsou řazeny na základě hodnoty vlastnosti Caption položek), stBoth (kombinace předchozích dvou hodnot). |
TopItem |
Vlastnost je typu TListItem a obsahuje první položku, kterou uživatel momentálně v seznamu vidí. Respektuje tedy, o kolik byl seznam již „odvinut“ (odscrollován). |
ViewStyle |
Určuje, jak jsou položky v seznamu zobrazeny. Možné hodnoty: vsIcon (každá položka je zobrazena jako ikona normální velikosti s popiskem pod obrázkem), vsSmallIcon (každá položka se zobrazí jako malá ikona s popiskem vpravo od obrázku), vsList (každá položka se zobrazí jako malá ikona s popiskem vpravo od obrázku, položky jsou však napevno rozmístěny ve sloupcích a na rozdíl od předchozí hodnoty nemohou být uživatelem přesunuty na jiné místo), vsReport (každá položka se objeví na vlastní řádce, nejlevější sloupec obsahuje malou ikonu a popisek, další sloupce obsahují „podpoložky“. Každý sloupec má záhlaví (viz ShowColumnHeader). Příklad použití této vlastnosti následuje v další podkapitole. |
VisibleRowCount |
Obsahuje nejvyšší počet řádků, který může být najednou v seznamu viditelný. Jsou započítávány jen plně viditelné řádky. |
*** - důležitá poznámka související s vlastností Selected: pokud jste pozorně četli popis této vlastnosti v tabulce, možná vám nemuselo být jasné, jak je možné, že Selected obsahuje jednou přímo označenou položku (tedy typ TListItem), a jednou máme „testovat vlastnost Selected jednotlivých položek menu“. Proč má mít každá položka svou vlastnost Selected obsahující označenou položku? Odpověď je prostá –
není jen jedna vlastnost Selected. Seznam jako celek (tedy TListView) obsahuje jednu vlastnost Selected, jejíž hodnotou je označená položka. A dále každá položka seznamu má svou vlastní vlastnost Selected, která je logického typu Boolean a která pouze říká „ano, moje položka je vybrána“ nebo „ne, moje položka není vybrána“.
Příklad použití komponenty ListView a vlastnosti ViewStyle
Příklad na ListView jsme si prohlédli v předchozím dílu seriálu, nicméně dnes se podíváme na aplikaci demonstrující, jak může vypadat seznam při různém nastavení hodnoty vlastnosti ViewStyle. Kromě této vlastnosti si také ukážeme, jaký vliv má nastavení hodnoty vlastnosti HotTrack.
Vytvořte aplikaci, na hlavní formulář (frmHlavni) umístěte komponenu ListView (ListView) a komponentu ImageList (ImageList). Tato komponenta nám bude sloužit jako „zdroj“ zobrazených položek v komponentě ListView. Dále na formulář umístěte komponentu RadioGroup (RadioGroup), tlačítko (btnKonec) a zatrhávací pole (CheckBox, Name = cbHotTrack).
Nyní je nutné do seznamu obrázků (ImageList) několik obrázků přidat. Poklepejte proto na ikonu komponenty ImageList, v otevřeném dialogu zvolte Add a najděte někde několik bitmap nebo ikon. Pokud nemáte své nevyčerpatelné zdroje, můžete zkusit použít např. podadresář Images\Icons adresáře, ve kterém máte nainstalovány Delphi, nicméně úspěch vám nezaručuji – záleží na verzi a typu instalace.
Následuje zdrojový kód celého modulu (z důvodu názornosti jsou důležitá nastavení a inicializace provedeny v rámci event handleru události OnCreate hlavního formuláře):
unit Hlavni;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, ExtCtrls;
type
TfrmHlavni = class(TForm)
ListView: TListView;
ImageList: TImageList;
RadioGroup: TRadioGroup;
btnKonec: TButton;
cbHotTrack: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure btnKonecClick(Sender: TObject);
procedure RadioGroupClick(Sender: TObject);
procedure cbHotTrackClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmHlavni: TfrmHlavni;
implementation
{$R *.DFM}
procedure TfrmHlavni.FormCreate(Sender: TObject);
var
I: Integer;
PolozkaSeznamu: TListItem;
Sloupec: TListColumn;
begin
frmHlavni.Caption := `Ukázka práce s komponentou ListView`;
cbHotTrack.Caption := `Hot Track`;
btnKonec.Caption := `&Konec`;
RadioGroup.Columns := 1;
RadioGroup.Items.Add(`vsIcon`);
RadioGroup.Items.Add(`vsSmallIcon`);
RadioGroup.Items.Add(`vsList`);
RadioGroup.Items.Add(`vsReport`);
RadioGroup.ItemIndex := 0;
with ListView do
begin
HotTrack := False;
SmallImages := ImageList;
LargeImages := ImageList;
for I := 0 to (ImageList.Count - 1) do begin
PolozkaSeznamu := Items.Add;
PolozkaSeznamu.Caption := `Položka ` + IntToStr(I);
PolozkaSeznamu.ImageIndex := I;
end;
Sloupec := Columns.Add;
Sloupec.Caption := `Sloupec 1`;
Sloupec.Width := 110;
Sloupec := Columns.Add;
Sloupec.Caption := `Sloupec 2`;
Sloupec.Width := 110;
end;
end;
procedure TfrmHlavni.btnKonecClick(Sender: TObject);
begin
Application.Terminate;
end;
procedure TfrmHlavni.RadioGroupClick(Sender: TObject);
begin
ListView.ViewStyle := TViewStyle(RadioGroup.ItemIndex);
end;
procedure TfrmHlavni.cbHotTrackClick(Sender: TObject);
begin
ListView.HotTrack := cbHotTrack.Checked;
end;
end.
Poznámky ke zdrojovému kódu
- V rámci obsluhy události OnCreate nejprve nastavíme titulky hlavního formuláře a tlačítka.
- Pak vytvoříme 4 přepínací tlačítka v rámci skupiny RadioGroup.
- Následně provedeme důležité inicializace prohlížeče seznamu: nastavení hodnot HotTrack, SmallImages a LargeImages. Do posledních dvou zmíněných vlastností bez uzardění přiřadíme náš seznam obrázků – ImageList.
- Pak do seznamu přidáme několik položek – co obrázek v seznamu obrázků ImageList, to položka v prohlížeči seznamu ListView.
- Nakonec v seznamu vytvoříme dva sloupce (pro demonstraci stylu vsReport).
- Po klepnutí na některé přepínací tlačítko ze skupiny RadioGroup nastavíme příslušný styl do vlastnosti ViewStyle. Všimněte si, že celou tuto akci zajišťuje jedna jediná řádka kódu – přiřazení hodnoty RadioGroup.ItemIndex s přetypováním na typ TViewStyle.
- Zatržení políčka cbHotTrack mění (nepříliš překvapivě) nastavení hodnoty vlastnosti HotTrack.
Metody komponenty ListView
Podívejme se na nejdůležitější metody komponenty ListView:
Metoda AlphaSort
Seřadí položky v ListView. Pokud existuje obsluha události OnCompare, AlphaSort použije k seřazení položek tuto obsluhu, v opačném případě seřadí položky vzestupně podle abecedy. V případě úspěchu vrací metoda True.
Metoda Arrange
Rozmístí ikony v závislosti na hodnotě parametru Code. Funguje pouze v případě, že ViewStyle = vsIcon nebo ViewStyle = vsSmallIcon. Možné hodnoty: arAlignBottom (seřadí ikony podle spodního okraje), arAlignLeft (podle levého okraje), arAlignRight (podle pravého okraje), arAlignTop (podle horního okraje), arDefault (default hodnota, která standardně podél horního okraje), arSnapToGrid („přichytí“ položky na nejbližší možnou čáru mřížky).
Metoda CustomSort
Seřadí položky v ListView. Použije k tomu funkci zadanou v parametru – viz příklad, ve kterém chceme k řazení použít funkci Porovnej. Výsledkem bude seznam v obráceném pořadí podle abecedy.
function Porovnej(Polozka1, Polozka2: TListItem;
ParamSort: integer): integer; stdcall;
begin
Result := -AnsiCompareText(TListItem(Polozka1).Caption,
TListItem(Polozka2).Caption);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ListView1.CustomSort(@Porovnej, 0);
end;
Metoda FindCaption
Vrátí položku ze seznamu, jejíž titulek (Caption) odpovídá zadanému (hledanému) titulku. Je možné nastavit celou řadu parametrů:
- Je-li parametr Inclusive = True, je první „testovanou“ položkou v seznamu položka specifikovaná parametrem StartIndex. Pokud je Inclusive = False, prohledává (testuje) se od položky, která následuje za položkou specifikovanou parametrem StartIndex.
- Je-li parametr Wrap = True, prohledávání pokračuje od začátku seznamu, není-li nalezena shoda od začátku prohledávání do konce seznamu.
- V parametru Value uvádíme hodnotu, kterou testujeme, tedy metoda FindCaption vrací první nalezenou položku, jejíž titulek (Caption) odpovídá hodnotě zadané v parametru Value.
- Je-li hodnota parametru Partial = True, považuje se za úspěch i shoda podřetězce (nemusí tedy být dosaženo úplné shody, např. „Počítač“ a „Počítačové“ se považuje za shodné). Pokud je hodnota parametru Partial = False, musí titulek a hodnota Value odpovídat zcela přesně.
Pokud není nalezena žádná odpovídající položka, je vrácena hodnota nil. V případě této metody asi neuškodí uvést si její úplný funkční prototyp (hlavičku):
function FindCaption(StartIndex: Integer; Value: string;
Partial, Inclusive, Wrap: Boolean): TListItem;
Metoda FindData
Vrátí položku ze seznamu, jejíž vlastnost Data (přesněji řečeno hodnota této vlastnosti) odpovídá zadané (hledané) hodnotě. O této metodě a o jejích parametrech platí totéž co o metodě předchozí: parametry Inclusive, StartIndex, Wrap a Value mají stejný význam jako v předchozím odstavci. Testuje se shoda hodnoty parametru Value s vlastností Data. Opět si uvedeme hlavičku:
function FindData(StartIndex: Integer; Value: Pointer;
Inclusive, Wrap: Boolean): TListItem;
Metoda GetNearestItem
Vrátí položku ze seznamu, která je nejblíže zadanému bodu (v přímém směru). Bod je zadán v parametru této metody, stejně jako směr, který se má testovat. Směr může nabývat jednu z následujících hodnot:
- sdLeft – prohledává se směrem doleva od zadaného bodu,
- sdRight - prohledává se směrem doprava od zadaného bodu,
- sdAbove - prohledává se směrem nahoru od zadaného bodu,
- sdBelow - prohledává se směrem dolů od zadaného bodu,
- sdAll – vrátí nejbližší položku, ať již leží v libovolném směru.
Není-li nalezena žádná položka, vrací metoda hodnotu nil.
Metoda GetNextItem
Velmi výkonná metoda. Vrátí položku ze seznamu, přičemž je možné zadat několik parametrů: „startovní“ položku (tj. počáteční položku, od které se má hledat), směr prohledávání (možné jsou stejné hodnoty jako u metody GetNearestItem) a stav položky, který může být:
- isNone – jsou vraceny pouze položky ve výchozím (tj. v žádném speciálním) stavu,
- isCut - jsou vraceny pouze položky označené pro operace vyřízni (Cut) a vlož (Paste),
- isDropHilited - jsou vraceny pouze položky označené jako cíle pro operaci drag-and-drop (táhni a pusť),
- isFocused – je vracena hodnota vlastnosti ItemFocused,
- isSelected - jsou vraceny pouze vybrané položky,
- isActivating – jsou vraceny pouze aktivní položky.
Metoda IsEditing
Metoda vrací True v případě, že některá položka v seznamu je právě editována (přesně řečeno uživatel zrovna edituje její titulek).
Metoda Scroll
Metoda posune (scrolluje) seznam o zadanou vzdálenost.
Metoda StringWidth
Metoda vrací šířku zadaného řetězce (v pixelech) za předpokladu, že bude použit aktuální font komponenty ListView. Je to vhodné např. v případě, že se potřebujete ujistit, jestli se nějaký řetězec do seznamu celý vejde (nebo když chcete nastavit šířku ListView podle některé položky, apod.).
Metoda UpdateItems
Metoda aktualizuje seznam položek. Je vhodná v případě, že máme v seznamu několik položek, ale víme, že se hodnota některé z nich mezitím kdesi (jinde) změnila. Je možné zadat rozpětí položek, které se budou aktualizovat, ostatní zůstanou beze změny.
Události komponenty ListView
Na závěr dnešního dílu seriálu se podíváme na několik události komponenty ListView, viz následující tabulka:
Událost |
Popis |
OnChange |
Událost se objeví ihned poté, co byla některá z položek seznamu ListView (editována). |
OnChanging |
Událost se objeví v okamžiku, kdy se objeví požadavek na změnu některé položky (tedy těsně předtím, než začne vlastní editace). V tomto okamžiku je samozřejmě možné (prostřednictvím parametru AllowChange) požadovanou změnu nepovolit. |
OnColumnClick |
Objeví se po klepnutí myší na záhlaví sloupce. Více o sloupcích a jejich záhlaví viz předchozí podkapitoly. |
OnCompare |
Objeví se v okamžiku, kdy dvě položky potřebují být seřazeny při řazení celého seznamu. OnCompare je volána, pokud hodnota SortType je stData nebo stBoth, když je volána metoda AlphaSort, nebo když je volána metoda CustomSort bez zadaného parametru SortProc. V parametrech této metody předáváme dvě položky, které mají být setříděny. |
OnDeletion |
Událost se objeví v okamžiku, kdy se objeví požadavek na výmaz (zrušení) některé položky. |
OnEdited |
Událost se objeví ihned poté, co byl editován titulek (Caption) položky. Tato událost je tedy vhodná v případě, že chcete reagovat na některou hodnotu, kterou uživatel zadal, případně když chcete tuto hodnotu úplně změnit. Tato událost se může objevit pouze v tom případě, že hodnota vlastnosti ReadOnly je nastavena na False. |
OnEditing |
Událost se objeví v okamžiku, kdy uživatel začne měnit (editovat) titulek (Caption) některé položky. Jako u všech událostí typu „před“ je i zde možné celou akci ještě zakázat – nastavením hodnoty parametru AllowEdit na False. |
OnInsert |
Událost je generována ihned poté, co byla do seznamu přidána nová položka. V parametru je předána položka, která byla právě vložena do seznamu. |
Je vidět, že komponenta ListView je velmi mocná, že umožňuje nebývalé penzum činností, přičemž dává programátorům možnost nastavovat celou řadu parametrů a možností zobrazení a chování. Pokud si zvyknete ji pravidelně využívat, těžko byste si na ni odvykali.