Witam, mam przykładowo komponent ListView, chciałbym dodać nową właściwość do tego komponentu właściwość/property typu String, i chciałbym aby ta właściwość była widoczna w Object Inspector z którego mógłbym w prosty sposób edytować ją. Czy ktoś pomoże mi w jaki sposób to zrobić ? pozdrawiam
Aby właściwość była widoczna w Object Inspector trzeba utworzyć nowy komponent dziedziczący po ListView i go zainstalować przykładowy kod może wyglądać tak:
unit MyListView;
interface
uses
Classes, ComCtrls;
type
TMyListView = class(TListView)
private
fMyNewProperty: string; //prywatna zmienna do przechowaywania wartosci
public
//trzeba nadpisac kontruktor
constructor Create(AOwner: TComponent); override;
published
//nowa wlasciwosc
property MyNewProperty: string read fMyNewProperty write fMyNewProperty;
end;
procedure Register;
implementation
constructor TMyListView.Create(AOwner: TComponent);
begin
inherited Create(AOwner); //wywolaj konstruktor odziedziczony
fMyNewProperty:= ''; //wartosc domyslna nowej wlasciwosci
end;
procedure Register;
begin
//komponent zostanie zarejestrowany na zakladce MyComponents i
//bedzie sie nazywal TMyListView
RegisterComponents('MyComponents', [TMyListView]);
end;
dziękuję za kod, tylko jest mały problem chciałbym żeby ta właściwość była dostępna w każdym itemie, przykładowo :
listview1.items[0].mynewproperty:='string';
pomógłbyś mi jeszcze z tym probowałem poprawić kod ale nie poradze sobie.
unit MyListView;
interface
uses
Classes, ComCtrls;
type
TMyListItem = class(TListItem)
private
fMyNewItemProperty:string; //prywatna zmienna do przechowaywania wartosci
public
constructor Create(AOwner:TListItems);
published
property MyNewItemProperty: string read fMyNewItemProperty write fMyNewItemProperty;
end;
TMyListView = class(TListView)
private
fMyNewProperty: string; //prywatna zmienna do przechowaywania wartosci
public
//trzeba nadpisac kontruktor
constructor Create(AOwner: TComponent); override;
protected
function CreateListItem: TListItem; override;
published
//nowa wlasciwosc
property MyNewProperty: string read fMyNewProperty write fMyNewProperty;
end;
procedure Register;
implementation
constructor TMyListItem.Create(AOwner:TListItems);
begin
inherited Create(AOwner);
fMyNewItemProperty:='Domyślna wartość';
end;
constructor TMyListView.Create(AOwner: TComponent);
begin
inherited Create(AOwner); //wywolaj konstruktor odziedziczony
fMyNewProperty:= ''; //wartosc domyslna nowej wlasciwosci
end;
function TMyListView.CreateListItem:TListItem;
begin
Result:=TMyListItem.Create(Items);
end;
procedure Register;
begin
//komponent zostanie zarejestrowany na zakladce MyComponents i
//bedzie sie nazywal TMyListView
RegisterComponents('MyComponents', [TMyListView]);
end;
//Użycie:
TMyListItem(listview1.Selected).MyNewItemProperty:='Nowa wartość';
TMyListItem(listview1.items[0]).MyNewItemProperty:='string';
Z tym że tego nie potrzebujesz.
Jeżeli masz powiedzmy 3 kolumny to, po stworzeniu wiersza możesz dodać nawet 20 items'w do każdego wiersza.
I tak wyświetlą się tylko 3 kolumny.
ziom7 napisał(a):
dziękuję za kod, tylko jest mały problem chciałbym żeby ta właściwość była dostępna w każdym itemie, przykładowo :
listview1.items[0].mynewproperty:='string';
pomógłbyś mi jeszcze z tym probowałem poprawić kod ale nie poradze sobie.
A po co tak kombinować, skoro nie radzisz sobie z podstawowymi zagadnieniami tworzenia własnych komponentów. Wykorzystuj własność Data
itemów TListView
. Możesz w niej przechować prostą klase dziedziczącą po TObject
z własnością string
a nawet większą ilością danych poprzez dodatkowe inne własności, jeżeli zajdzie taka potrzeba. Poprzednik już Tobie pokazał jak tworzyć własną klasę. Tylko, że tutaj dziedziczysz po TObject. I na upartego nie musisz nic ustawiać w konstruktorze jako inicjalizacje tej zmiennej typu string. Chociaż dla poprawności i pewności, że wszystko jest ok - powinno się to zrobić, tak jak zostało to pokazane.
EDIT: przykład - wycinek kodu z własnego programu, w trakcie tworzenia. Oczywiście wszystkie obiekty są tworzone jak należy, co nie do konca w tym kodzie widać - na przykład po zmiennej Ico
. A kod działa tak, jak tego oczekuje. Chciałem tylko wkleić na szybko żeby przykładem pomóc zrozumieć ideę użycia własności Data
.
//...
type
TItemKind = (ikDirectory, ikFile, ikSymLink, ikUpDir);
TFileData = class(TObject)
public
FullPath : string;
FileSize : Cardinal;
ItemKind : TItemKind;
IsFileSelected : boolean;
end;
//...
var
//...
H : THandle;
Ico : TIcon;
Ext : string;
LI : TListItem;
FD : TFileData;
WFD : TWIN32FindData;
FileInfo : SHFILEINFO;
begin
//...
FD := TFileData.Create;
FD.FullPath := APath + WFD.cFileName;
FD.IsFileSelected := False;
FD.ItemKind := ikFile;
FD.FileSize := WFD.nFileSizeLow;
LI := FilesLV.Items.Add;
LI.Caption := ChangeFileExt(WFD.cFileName, '');
Ext := ExtractFileExt(WFD.cFileName);
if Ext = '' then
begin
LI.SubItems.Add('');
end
else
begin
LI.SubItems.Add(Copy(Ext, 2, Length(Ext) - 1));
end;
SHGetFileInfo(PChar(FD.FullPath), 0, FileInfo,
SizeOf(FileInfo), SHGFI_ICON or SHGFI_SMALLICON);
Ico.Handle := FileInfo.hIcon;
FilesIL.AddIcon(Ico);
LI.ImageIndex := FilesIL.Count - 1;
LI.SubItems.Add(SeparateDigits(FD.FileSize));
LI.Data := FD;
//...