Jak dodać nową właściwość do aktualnego komponentu ?

0

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

0

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;
0

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.

0
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.

0
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;
//...

1 użytkowników online, w tym zalogowanych: 0, gości: 1