VCL Delphi

Title: Directly editing a ListBox
Question: How can I edit a listbox directly without the need for other components?
Answer:
This subject was already treated in article ID_729, I tried the code and it produced a lot of errors, besides the implementation was not satisfactory (apparently it was written by a deity!!), so here is my own implementation.
The trick is placing a TEdit over the item to edit it, I've chosen to edit an item by double clicking on it or pressing the Enter key.
Here is the constructor of my component:
//
inherited;
ListEdit := TEdit.Create(Self);
with ListEdit do
begin
Parent := Self;
Visible := False;
Left := 0;

//choose the color that suits you.
Color := clAqua;

BorderStyle := bsNone;
OnExit := EditExit;
OnKeyPress := EditKeyPress;
OnKeyDown := EditKeyDown;
end;
//
Setting the parent of the edit to Self makes the edit looks more a part of the listbox then an edit which is placed over it, setting the BorderStyle to bsNone enhance that effect.
The heart of this component is this peace of code:
//
if ItemIndex with Self do
begin
ListEdit.Height := ItemHeight;
ListEdit.Width := ClientWidth;
ListEdit.Visible := True;
ListEdit.Text := Items[ItemIndex];
ListEdit.Top := (ItemIndex*ItemHeight)-(ItemHeight*TopIndex);
ListEdit.Tag := ItemIndex;
ListEdit.SetFocus;
end;
//
This will give you access to the item you double clicked on, but what happens when you finished:
//
Self.Items[ListEdit.Tag]:= ListEdit.Text;
ListEdit.Visible:=False;
//
Completing the circle and the item is edited. I exit the edit by pressing the Enter key or choosing another item.
I am not really an expert in writing component and have been a while since I read on the subject, so I am very open for comment and suggestions.
You can download the component with a demo or take a look at the full source of the component right here:
unit EditListBox;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TEditListBox = class(TCustomListBox)
ListEdit : TEdit;
private
{ Private declarations }
protected
{ Protected declarations }
procedure DblClick; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
public
{ Public declarations }
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
procedure EditExit(Sender : TObject);
procedure EditKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
procedure EditKeyPress(Sender: TObject; var Key: Char);
published
{ Published declarations }
property Align;
//
// put here the properties of TCustomListBox
//
property OnStartDrag;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Additional', [TEditListBox]);
end;
{ TEditListBox }
constructor TEditListBox.Create(AOwner: TComponent);
begin
inherited;
ListEdit := TEdit.Create(Self);
with ListEdit do
begin
Parent := Self;
Visible := False;
Left := 0;
Color := clAqua;
BorderStyle := bsNone;
OnExit := EditExit;
OnKeyPress := EditKeyPress;
OnKeyDown := EditKeyDown;
end;
end;
procedure TEditListBox.DblClick;
begin
inherited;
with Self do
begin
ListEdit.Height := ItemHeight;
ListEdit.Width := ClientWidth;
ListEdit.Visible := True;
ListEdit.Text := Items[ItemIndex];
ListEdit.Top := (ItemIndex*ItemHeight)-(ItemHeight*TopIndex);
ListEdit.Tag := ItemIndex;
ListEdit.SetFocus;
end;
end;
destructor TEditListBox.Destroy;
begin
ListEdit.Free;
inherited;
end;
procedure TEditListBox.EditExit(Sender: TObject);
begin
Self.Items[ListEdit.Tag]:= ListEdit.Text;
ListEdit.Visible:=False;
end;
procedure TEditListBox.EditKeyDown;
begin
if Key = vk_return then
begin
Key := vk_tab ;
Self.SetFocus;
end;
end;
procedure TEditListBox.EditKeyPress;
begin
if Key = #13 then
key := #0;
end;
procedure TEditListBox.KeyDown;
begin
if key = vk_return then
begin
DblClick;
end;
inherited;
end;
end.