Prázdniny a dovolené jsou v plném proudu, takže dnes to bude něco méně náročného. Opět to bude vylepšování existujících komponent a tentokrát si položky v ListBoxu zobrazíme jako prvky RadioButtonu.
Bude to opravdu jednoduchý tip pro drobné vylepšení vzhledu ListBoxu. Funkčnost se nijak nezmění, tedy ani nezlepší. Pokud nám slouží ListBox výhradně pro výběr vždy jen jedné konkrétní položky z mnoha, můžeme přidat k jednotlivým řádkům "kolečko" z RadioButtonu. Tím ještě v uživateli umocníme představu o tom, že z ListBoxu má (resp. lze) vybrat opravdu jen jednu položku. Nezapomeňte tedy volbu Multiselect nastavit na False.
Postup je snadný. Umístěte na formulář ListBox a naplňte několika řádky dat. Dále musíme nejprve nastavit styl vykreslování ListBoxu na OwnerDraw, čím na sebe bereme veškerou zodpovědnost za jeho vzhled. V našem případě je to uděláno programově v události OnCreate a je zde nastavena i velikost řádku na 20 bodů. V události OnDrawItem pak kreslíme samotné prvky, kdy nakreslíme "rámeček", RadioButton a vypíšeme pak samotný text.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
procedure FormCreate(Sender: TObject);
procedure ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
procedure ListBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
ListBox1.Style := lbOwnerDrawVariable;
ListBox1.ItemHeight := 20;
end;
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
drawRect: TRect;
begin
with ListBox1.Canvas do
begin
FillRect(rect);
drawRect.Left := rect.Left + 1;
drawRect.Right := Rect.Left + 13;
drawRect.Bottom := Rect.Bottom;
drawRect.Top := Rect.Top;
if odSelected in State then DrawFrameControl(Handle, drawRect, DFC_BUTTON, DFCS_BUTTONRADIO or DFCS_CHECKED)
else DrawFrameControl(Handle, drawRect, DFC_BUTTON, DFCS_BUTTONRADIO);
TextOut(15, rect.Top + 3, ListBox1.Items[Index]);
end;
end;
procedure TForm1.ListBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
// ListBox1.ItemIndex := ListBox1.ItemAtPos(Point(x, y), True);
end;
end.
Pokud budete chtít ListBox opravdu "přeplácat", můžete přidat i automatické označení položek po najetí myší (příslušný řádek je označen v kódu jako poznámka) v události OnMouseMove, jak jsme si ukazovali nedávno. To už by bylo na uživatele ale asi příliš, proto to nechám na vaší úvaze.