Właściwość typu TListItems. Problem przy pisaniu komponentu

0

Witam! Pisząc (a raczej zaczynając pisać, bo póki co mam tylko wygląd) swój program zostałem zmuszony do napisania dla niego komponentu opartego na komponencie ListBox. Problem polega na tym, że chciałbym do Inspektora Obiektów dodać właściwość o typie TListItems tak jak ma to komponent ListView w swoim Items - do edycji wyskakuje takie okienko. Oczywiście nie mam zamiaru zamieniać oryginalnej właściwości Items ListBox'a. Zacząłem tak:

   uses ..., ComCtrls;
   ...
   private
     FContacts: TListItems;
     ...
     procedure SetContacts(Value: TListItems);
   published
     property Contacts: TListItems read FContacts write SetContacts;

Teraz aby w procedurze SetContacts skorzystać z instrukcji FContacts.Count

procedure TBBList.SetContacts(Value: TListItems);
begin
  FContacts:= Value;
  Items.Add(FContacts.Item[FContacts.Count - 1].SubItems[2]);
end;

Muszę wywołać takie coś:

FContacts.Create(...);

Pomyślałem, że mogę tego dokonać w konstruktorze komponentu (a w desktruktorze FContacts.Destroy). Problem w tym, że w miejsce trzykropek z kodu powyżej muszę wstawić parametr AOwner: TCustromListView i właśnie nie wiem co tam wstawić :) Próbowałem różnych rzeczy (wstawiać nil i co tylko pasowało). Efekty tego były różne. Raz się kompilowało raz nie. Jak się skompilowało to nie mogłem położyć komponentu na formie - "Access violation..." lub jak udało się go położyć to znowu "Access violation" podczas próby edycji owej właściwości. Czy ktoś byłby mi w stanie udzielić pomocy w usunięciu tego błędu lub wskazaniu jakiejś alternatywy? W Internecie znalazłem coś na wzór odpowiedzi na mój problem, ale brzmiała ono mniej więcej tak: "Nie można tak zrobić, bo nie" - a jak już to chciałbym wiedzieć dlaczego :).

0
sid_mb napisał(a)
procedure TBBList.SetContacts(Value: TListItems);
begin
  FContacts:= Value;
  Items.Add(FContacts.Item[FContacts.Count - 1].SubItems[2]);
end;

Nie wnikając w poprawność kodu - imo itemsy z list przydziela się przez Assign.. więc powinno być

FContacts.Assign(Value)

Jeśli zaś chodzi o właściwość AOwner - możesz chyba stworzyć w komponencie po prostu kolejny listbox, z którego 'na zewnątrz' wystawisz tylko ListItems? Nie zrozumiałem do końca efektu, który chcesz osiągnąć, ale to chyba to..

0

Z Assign to nie wiem, póki co moja wersja nie powodowała błędów - w zasadzie nie miała jeszcze okazji :). Chodzi mi o stworzenie takiej właściwości, która wyglądała by w Inspektorze Obiektów tak samo jak właściwość Items komponentu ListView. Wiem, że mogę zrobić tak iż będę kładł dodatkowy komponent ListView na formę i będę go mógł powiązać z ListBox'em. Z tym że tego właśnie chciałbym uniknąć.

0

Nikt Ci nie każe kłaść. Stwórz wirtualnie, a na zewnątrz wystaw tylko itemsy - od czego masz get/set?

0

Wrrr... zmęczony jestem. Nie 'wirtualnie', tylko w konstruktorze. Reszta - jak wyżej.

0

Mogę wstawić ListBox'a na formę i otworzyć "okienko" właściwości - brak błędów. Z tym, że później jest gorzej, błędy pamięci tu i tam. Chyba, że źle Ciebie zrozumiałem i zrobiłem coś nie tak, a kodu który wtedy napisałem już nie mam.

0

zamieść cały kod + dokładny opis co to ma być i co robić bo ja mam tylko mętlik jak na razie

0

Kod, który zamieściłem jest według mnie wystarczający. Z resztą i tak nie ma go póki co za wiele :) poza tym co dałem jest jeszcze w zasadzie tylko procedura OnDrawItem, której nie miałem jeszcze przyjemności wypróbować, a nie ma ona żadnego powiązana z tym co ja chcę zrobić. A co chcę zrobić/osiągnąć? To proste: włączcie Delphi, wstawcie komponent ListView na formę, sprawdźcie jego właściwość Items w Inspektorze Obiektów i zobaczcie jak ją edytować. I teraz chcę mieć takie coś w swoim komponencie opartym o ListBox.

0

Jeszcze się z tym męczysz? Przecież podałem Ci dokładne rozwiązanie. Tworzysz wewnętrznie drugi obiekt, którego property typu lista wystawiasz 'na zewnątrz'.

0

Ze stworzeniem obiektu nie ma problemu, ale jak wyciągnąć jego właściwość do property tego nie wiem. poza tym (teoretycznie) wystarczy mi wiedzieć co wpisać jako parametr Create:

FContacts.Create(?);
0
property MojaListaItems: TListItems read GetMojaListaItems write SetMojaListaItems;

a gdzieś w kodzie

function GetMojaLista: TListItems;
begin
  result := FMojaWewnetrznaLista.ListItems;
end;

Oczywiście musisz utworzyć w konstruktorze i zwolnić w destruktorze FMojaWewnetrznaLista.
blah blah..

0

P.S.
To oczywiście szkic kodu, nie dopisywałem tych wszystkich "TForm1" itede, bo nie wiem, w jakim komponencie chcesz to umieścić. Mam nadzieję że złapałeś ideę, jak nie - zamieść definicję swojej klasy, to Ci to dokładniej rozpiszę.

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