Umíme to s Delphi, 31. díl – chcete efektivně prohlížet seznamy?

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.

Komponenta ListView

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.

Klepněte pro větší obrázek

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.

Klepněte pro větší obrázek

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.

Diskuze (1) Další článek: Podpora PHP do FrontPage

Témata článku: Software, Prohlížeče, Programování, Vhodný uživatel, Důležitá událost, Sloupec, Požadovaná vzdálenost, Přepínací tlačítko, Opačný směr, ISF, SDL, Položka, Seznam, Pointer, Opačný případ, DEL, Tito, Výsledné dílo, Důležitý údaj, Označení, Toto, Díl, Důležitý sloupec


Určitě si přečtěte

Google chystá funkci, která z chytrého Gmailu udělá hloupý Gmail
Lukáš Václavík
SoukromíGmailGoogle
Jak v prohlížeči vypnout oznámení zasílaná webovými stránkami

Jak v prohlížeči vypnout oznámení zasílaná webovými stránkami

** Obtěžují vás neustálé dotazy webů, zda chcete zobrazovat oznámení? ** Můžete je zakázat, a to jak kompletně, tak i pro jednotlivé stránky ** Připravili jsme návody pro Chrome, Firefox, Edge a Operu

Karel Kilián | 11

Karel Kilián
Jak na InternetTipyProhlížeče
AMD uvádí grafické karty Radeon RX 6800, 6800 XT a 6900 XT. Útočí přímo na modely od Nvidie

AMD uvádí grafické karty Radeon RX 6800, 6800 XT a 6900 XT. Útočí přímo na modely od Nvidie

** AMD představilo tři nové grafické karty ** Všechny s architekturou RDNA2, kterou používají i PS5 a Xbox Series ** Karty útočí přímo na GeForce RTX 3000

Karel Javůrek | 77

Karel Javůrek
Radeon RX 6000Grafické kartyAMD
Elon Musk podpořil Signal jako náhradu WhatsAppu. Aplikaci okamžitě zavalili uživatelé
Markéta Mikešová
WhatsAppElon MuskFacebook
Teď už Chromium ovládne Windows 10 úplně. Microsoft dokončil WebView2

Teď už Chromium ovládne Windows 10 úplně. Microsoft dokončil WebView2

** Před dvěma lety se Microsoft zasnoubil s Chromem ** Nový Edge není zdaleka jejich jediné dítě ** Ještě důležitější je komponenta WebView2

Jakub Čížek | 53

Jakub Čížek
Windows 10ChromeSoftware
Google spouští vlastní VPN a konkurenci se to vůbec nelíbí
Lukáš Václavík
SoukromíVPNGoogle
Uživatelé hlásí problémy s jednou z listopadových záplat pro Windows 10
Karel Kilián
Windows UpdateAktualizaceWindows 10

Aktuální číslo časopisu Computer

Jak prodloužit výdrž notebooku

Velké testy: gamepady a inkoustové tiskárny

Důkladný test Sony Playstation 5