Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   TCategoryPanel.ControlCount immer = 1 (https://www.delphipraxis.net/184379-tcategorypanel-controlcount-immer-%3D-1-a.html)

Nils S. 20. Mär 2015 19:47

TCategoryPanel.ControlCount immer = 1
 
Guten Abend zusammen,

ich bin etwas verwirrt...
Wenn ich in einem TCategoryPanel (nicht TCategoryPanelGroup) ein ControlCount durchführe, bekomme ich immer 1 zurück.
Packe ich aber die gleichen Komponenten (Labels, Comboboxen, Buttons und RadioButtons) beispielsweise in ein TPanel, bekomme ich die richtige Anzahl zurück.

Kann mir jemand sagen, warum das so ist?
Muss man beim TCategoryPanel noch irgendwas beachten?

Würde mich über Rückmeldungen freuen.

Danke.

MfG

Nils

Delbor 21. Mär 2015 06:20

AW: TCategoryPanel.ControlCount immer = 1
 
Hi Nils S

Ich habe dieses Controlcount bisher nie gebraucht, da auf meinen Categorypanels jeweils eine Frameinstanz liegt - ausser auf einem, das zusätzlich ein Panel enthält. Eine probeweise Abfrage ergab jedoch auch bei mir 1. Scheint ein Fehler zu sein.
Ich arbeite mit DelphiXE4.

Gruss
Delbor

Nils S. 21. Mär 2015 07:58

AW: TCategoryPanel.ControlCount immer = 1
 
Hi Delbor,

danke erst Mal, für die Antwort.
Habe mir schon fast gedacht, dass es sich um 'nen Bug handelt.
Also tatsächlich immer noch ein TPanel da rein setzen...

himitsu 21. Mär 2015 08:55

AW: TCategoryPanel.ControlCount immer = 1
 
Erstmal wäre es eine gute Idee gewesen, wenn du einfach mal nachsiehst, was das für ein Control ist (ClassName),
dann wäre dir sofort aufgefallen, daß es ganz richtig so ist.

Also entweder
Delphi-Quellcode:
(CategoryPanel1.Controls[0] as TCategoryPanelSurface).ControlCount
oder du benutzt die offizielle API, also
Delphi-Quellcode:
CategoryPanel1.GetChildren
. :stupid:
Delphi-Referenz durchsuchenTWinControl.GetChildren

Nils S. 3. Mai 2015 06:33

AW: TCategoryPanel.ControlCount immer = 1
 
So, ich habe endlich mal wieder Zeit gefunden, mich mit Deplhi zu beschäftigen. :)
Auch Dir erstmal dankte, himitsu.

Bei dem Tipp mit dem Klassennamen bin ich etwas verwirrt.
Der ist doch TCategoryPanel oder nicht?
Und inwiefern hilft mir das dann weiter um zu wissen, dass ich mit ControlCount nicht die Anzahl der Controls auf dem Panel ermitteln kann?

Ich habe die verschiedenen Varianten mal ausprobiert.
Ich möchte mit dem ermittelten Wert eine for Schleife ausführen, um bestimmte Komponenten (TComboBox) zu leeren.

Wenn ich die offizielle API verwende, will Delphi von mir noch zwei Parameter haben, wovon der zweite wohl nicht relevant ist und der erste, der sich Proc nennt, ist wohl eine Callback Funktion.
Ich habe mal etwas gegoogelt und dabei herausgefunden, dass es sich bei einer Callback Fuktion um eine Funktion handelt, die ich selbst definieren kann und ausgeführt wird und einen Wert zurückliefert.
Aber wofür brauche ich das? Ich möchte ja nur die Anzahl der Komponenten damit ermitteln und das Ergebnis in der for Schleife verwenden.

Mit der anderen Variante funktioniert das Ermitteln der Komponenten super.
Allerdings kann ich in der for Schleife auch nicht TCategoryPanel1.Controls[i] verwenden, da es immer zu dem Fehler "Listenindex überschreitet das Maximum(1)' kommt.
Wahrscheinlich aus dem selben Grund, weshalb man ControlCount nicht verwenden kann (was ich ja bislang, wie in der ersten Frage dieses Posts beschrieben, noch nicht verstanden habe).

Hier mal der Code:

Delphi-Quellcode:
procedure TGeneralCtrl.ResetFilter(Cpl: TCategoryPanel);
var
  i, cplComponents :integer;
begin
  //Anzahl Komponenten ermitteln - 1.
  CplComponents := (Cpl.Controls[0] as TCategoryPanelSurface).ControlCount - 1; //<--Funktioniert.
  //ComboBoxen zurücksetzen.
  for i := 0 to cplComponents do
  begin
    if Cpl.Controls[i] is TComboBox then                                       //<--Fehler bei zweitem Durchlauf.
    begin
      (Cpl.Controls[i] as TComboBox).Text := '';
    end;
  end;
end;
Würde mich freuen, wenn ich noch ein paar Erklärungen bekomme. :)

Uwe Raabe 3. Mai 2015 07:19

AW: TCategoryPanel.ControlCount immer = 1
 
Das TCategoryPanel hat nur ein einziges Child-Control vom Typ TCategoryPanelSurface. In diesem stecken dann die einzelnen Conrols, die du sehen kannst. Du musst also nicht über die Controls von TCategoryPanel iterieren, sonden über die des TCategoryPanelSurface, was du über Cpl.Controls[0] erreichts. Die Typumwandlung mittels
Delphi-Quellcode:
as
ist wohl nicht mal nötig.

Nils S. 3. Mai 2015 07:46

AW: TCategoryPanel.ControlCount immer = 1
 
Achso.

Also ist Cpl.Controls[0] quasi das TCategoryPanelSurface und dieses enthält alle Controls.

Um an die einzelnen Controls zu kommen müsste ich jetzt Cpl.Controls[0].Controls[i] verwenden, was aber nicht geht.
Daher muss ich die Typumwandlung mit as wohl machen (die Schleife klappt jetzt sogar :)).

Aber da ich ja auch lernen und verstehen will,
warum funtkioniert z.B. bei einem TPanel Controls/ControlCount, bei einem TCategoryPanel aber nicht, bzw. wieso hat TCategoryPanel dieses Surface, was alle Controls enthält?
Und woran erkennt man sowas bei einer Komponente oder muss man die ganze Klasse durchstöbern, ob man irgendwo ein TXyzSurface findet?

Uwe Raabe 3. Mai 2015 08:18

AW: TCategoryPanel.ControlCount immer = 1
 
Zitat:

Zitat von Nils S. (Beitrag 1300070)
Also ist Cpl.Controls[0] quasi das TCategoryPanelSurface und dieses enthält alle Controls.

So ist es.

Zitat:

Zitat von Nils S. (Beitrag 1300070)
Um an die einzelnen Controls zu kommen müsste ich jetzt Cpl.Controls[0].Controls[i] verwenden, was aber nicht geht.
Daher muss ich die Typumwandlung mit as wohl machen

Eigentlich reicht hier auch eine Umwandlung in TWinControl, denn dort wurden die Eigenschaften Controls und ControlCount eingeführt.

Zitat:

Zitat von Nils S. (Beitrag 1300070)
Aber da ich ja auch lernen und verstehen will,

:thumb:

Zitat:

Zitat von Nils S. (Beitrag 1300070)
warum funtkioniert z.B. bei einem TPanel Components/ComponentCount, bei einem TCategoryPanel aber nicht, bzw. wieso hat TCategoryPanel dieses Surface, was alle Controls enthält?

Das ist ein durchaus übliches Pattern (siehe auch TCategoryButtons). Die Instanz von TCategoryPanelSurface ist nicht unbedingt genau ein TCategoryPanelSurface, sondern kann auch davon abgeleitet sein. Die tatsächlich verwendete Klasse wird in der virtuellen Methode GetCategoryPanelSurfaceClass bestimmt, die in einer Ableitung von TCategoryPanel durchaus etwas anderes zurückgeben kann.

Zitat:

Zitat von Nils S. (Beitrag 1300070)
Und woran erkennt man sowas bei einer Komponente oder muss man die ganze Klasse durchstöbern, ob man irgendwo ein TXyzSurface findet?

Ich finde sowas eigentlich immer durch Analyse der Sourcen (mach ich immer als Erstes, wenn eine neue Version rauskommt). Gerade für diesen Fall führt ein Blick in die Methode GetChildren meist schnell in die richtige Richtung.

So ein schickes UML-Diagramm wäre da sicher ganz hilfreich, aber das müsste nicht nur jemand einmal erstellen, sondern auch regelmäßig pflegen. Bis dahin gilt: Use the source, Luke!

himitsu 3. Mai 2015 11:30

AW: TCategoryPanel.ControlCount immer = 1
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1300068)
Die Typumwandlung mittels
Delphi-Quellcode:
as
ist wohl nicht mal nötig.

Doch ist ist, denn was passiert wohl, wenn Emba diese Komponente mal umbaut?
Wenn man ein undokumentiertes Verhalten benutzt, dann sollte man wenigstens eine "kleine" Sicherheitsprüfung einbauen.
Oder man benutzt gleich den "offiziellen" Weg.

Sir Rufo 3. Mai 2015 12:11

AW: TCategoryPanel.ControlCount immer = 1
 
Ein Control brauche ich nicht zu casten wenn ich davon die ChildControls haben möchte.

Wenn Emba diese Komponente umbaut und es kommen keine Controls dann kompiliert das Programm nicht. Mit einem Cast stelle ich das dann zur Laufzeit fest.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:35 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz