Tworzę kontrolkę dziedziczącą po TCustomListBox
, w której właściwość Items
musi być niewidoczna dla programisty;
Chciałbym, by kontrolka korzystała z własnej listy, która będzie zadeklarowana jako macierz rekordowa. Deklaracja:
type
TExplorerContentObjectRec = packed record
Caption: String;
IconIndex: TExplorerObjectIconIndex;
end;
TExplorerContentArr = array of TExplorerContentObjectRec;
TExplorerContent = class(TPersistent)
private
FContentArr: TExplorerContentArr;
public
constructor Create();
destructor Destroy(); override;
end;
THDDExplorer = class(TCustomListBox)
private
FContent: TExplorerContent;
end;
Podczas tworzenia obiektu klasy TExplorerContent
zeruję rozmiar macierzy FContentArr
przygotowując ją do pracy; Chcę, aby kontrolka nie korzystała z odziedziczonej właściwości Items
, tylko z mojej macierzy do tworzenia widocznych itemów z jakimś tekstem; W kontrolce klasy np. TListBox
tworzy się nowy item dzięki ListBox1.Items.Add('String')
i to właśnie dodany łańcuch jest wyświetlany w kontrolce, u mnie chcę, by wyświetlaną nazwą był łańcuch z pola FContentArr[Index].Caption
;
Sprawa jest o tyle denerwująca, że nie mogę (a przynajmniej nie wiem jak) kontrolce nakazać korzystania z mojej listy dowolnego typu, musi obsługiwać standardową Items: TStrings
; Mogę dodawać nowe pozycje do listy jedynie dodając nowe linie do standardowej listy Items
i one po dodaniu będą widoczne w kontrolce;
Co mnie interesuje - chcę móc tworzyć nowe pozycje w kontrolce ale nie uwidoczniać standardowej właściwości Items
;
Mam dwa rozwiązania:
- odziedziczyć właściwość
Items
z bazowej klasyTCustomListBox
i ukryć ją by nie było do niej dostępu spoza modułu nowej kontrolki, - nie dziedziczyć tej właściwości (w ogóle z niej nie korzystać), a utworzyć swoją listę (lub macierz) i nakazać kontrolce korzystać z niej (co wiąże się oczywiście z ręcznym zaprogramowaniem dodawania/usuwania elementów do/z listy);
Najchętniej wykorzystałbym swoją macierz, ale co i gdzie mam zaprogramować by podczas dodawania nowego rekordu do macierzy (w kodzie) dodała się także nowa pozycja do listy (w dizajnerze)?
Przykład: TListBox
Kładę sobie kontrolkę tej klasy na formularz:
w oknie inspektora obiektów wybieram właściwość Items
:
otwieram okienko do uzupełniania tej właściwości i dopisuję linię Pierwsza linia
:
zamykam okienko przyciskiem OK
; Patrząc na formularz w oknie projektanta widać, że kontrolka posiada jedną pozycję o treści Pierwsza linia
:
Dzięki temu, że dodając linię do właściwości Items
automatycznie na liście w kontrolce tworzy się nowa pozycja o tej treści;
Przykład: THDDExplorer (TCustomListBox)
W klasie np. THDDExplorer
tworzę sobie macierz FContentArr: TExplorerContentArr
jako prywatne pole klasy kontrolki; Nie korzystam w ogóle ze standardowej właściwości Items
- nie dziedziczę jej; Teraz w konstruktorze tej klasy dodaję jedną pozycję:
type
TExplorerContentObjectRec = packed record
Caption: String;
IconIndex: TExplorerObjectIconIndex;
end;
TExplorerContentArr: array of TExplorerContentObjectRec;
THDDExplorer = class(TCustomListBox)
private
FContentArr: TExplorerContentArr;
public
constructor Create(AOwner: TComponent); override;
{...}
end;
implementation
constructor THDDExplorer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
SetLength(FContentArr, 1);
FContentArr[0].Caption := 'Pierwsza linia';
FContentArr[0].IconIndex := eoiiDesktop; //to jest nieistotne
end;
Dodałem jednen element do macierzy, ale kontrolka nie posiada jeszcze żadnego widocznego elementu na liście (na formularzu lista jest pusta); Jakimi instrukcjami i gdzie mam dodać nowy element do listy, by był widoczny w kontrolce na formularzu wykorzystując łańcuch spod FContentArr[0].Caption
?
W najgorszym wypadku jeśli kontrolka musi obsługiwać standardową listę to po prostu odziedziczę właściwość Items
i chcąc dodać nowe elementy do listy będę dodawał puste łańcuchy do niej (czyli HDDExplorer.Items.Add('')
), równorzędnie uzupełniając moją macierz FContentArr
, a podczas malowania itema będę wykorzystywał dane z tej macierzy, a nie z Items
...
Zagmatwałem trochę, ale ciężko mi to opisać, a co dopiero zapytać Google... Przeglądnąłem wiele kursów tworzenia własnych kontrolek, ale nigdzie nie znalazłem odpowiedzi na moje pytanie; Jeśli ktoś nie zrozumie o co mi chodzi to postaram się opisać problem jeszcze dokładniej;