![]() |
Dynamisch erzeugte Komponenten ansprechen
Ich möchte einen kleinen PDF-Viewer bauen.
Es sollen mehrere PDFs auf einem Formular dynamisch angezeigt werden. Dazu habe ich ein PageControls, wo ich dynamisch die Seiten (Pages) erzeuge. Und danach erzeuge ich auf diesem Tab die Viewer-Componente, in dem Fall TDXPDFViewer von Devexpress.
Delphi-Quellcode:
procedure TF1.AddPage(ACaption: string; AControl: TcxPageControl);
var NewPage: TcxTabSheet; NewViewer: TdxPDFViewer; begin NewPage := TcxTabSheet.Create(AControl.Owner); NewPage.PageControl := AControl; NewPage.Caption := ACaption; NewPage.Name := 'Page' + inttostr(newPage.pageIndex); NewViewer := TDXPDFViewer.Create(NewPage); NewViewer.Parent := NewPage; AControl.activePage := NewPage; NewViewer.LoadFromFile(Temp_Dateiname_gl); end; Das aktuelle Tabsheet bekomme ich raus mit:
Delphi-Quellcode:
Meine Frage ist jetzt, wie spreche ich die Viewer-Komponente, die auf diesem
Showmessage('PageNAme: ' + Pcontrol.ActivePage.Name + #13#10 +
'PageIndex: ' + inttostr(PControl.ActivePage.PageIndex) + #13#10 + 'TABIndex: ' + inttostr(PControl.ActivePage.TabIndex) ); Tabsheet ist an? Mit Findcomponent? Wenn ja wie genau? |
AW: Dynamisch erzeugte Komponenten ansprechen
Das, was du bei deinen Komponenten als Owner beim Create angibst (hier dein TabSheet), darin kannst du dann mit DeinTabSheet.FindComponent auch danach suchen.
Oder manuell DeinTabSheet.Components nach dem Typ durchsuchen, ansatt mit FindComponent nach dem Namen (NewViewer.Name hättest du doch bestimmt noch gesetzt) Owner -> x.Components und x.FindComponent und
Delphi-Quellcode:
for var C in x do
Parent -> x.Controls und x.FindControl (kein
Delphi-Quellcode:
, weil es keinen TEnumerator dafür gibt, was mich erstaunt, dass es das nicht gibt)
for var C in x.GetControls do
|
AW: Dynamisch erzeugte Komponenten ansprechen
Hier ist mal noch eine Funktion die ich benutzt habe um Controls recursiv zu finden. Vllt. hilft dir das ja.
Delphi-Quellcode:
function FindFirstControl(const aControl: TWinControl; AClass: TClass): TControl; var i: Integer; begin Result := nil; for i := 0 to aControl.ControlCount -1 do begin if aControl.Controls[i] is AClass then begin Result := aControl.Controls[i]; break; end else begin Result := FindFirstControl(TwinControl(aControl.Controls[i]), AClass); if (Result <> nil) then break; end; end; end; |
AW: Dynamisch erzeugte Komponenten ansprechen
Eine einfache Methode (ohne mit FindComponent suchen zu müssen) wäre die Klasse TcxTabSheet im Form mit dem gleihem Tyenbezeichner abzuleiten und hier den Viewer zu legen.
Beispiel:
Delphi-Quellcode:
UnitName muss dabei die Unit sein, die TcxTabSheet enthält.type TcxTabSheet = class(UnitName.TcxTabSheet) private Viewer : TDXPDFViewer; end; TF1 = class(TForm) ... Erzeugt wird der
Delphi-Quellcode:
So hast du bei TcxTabSheet immer direkt den Viewer verfügbar.
procedure TF1.AddPage(ACaption: string; AControl: TcxPageControl);
var NewPage: TcxTabSheet; begin NewPage := TcxTabSheet.Create(AControl.Owner); NewPage.PageControl := AControl; NewPage.Caption := ACaption; NewPage.Name := 'Page'*+ inttostr(newPage.pageIndex); NewPage.Viewer := TDXPDFViewer.Create(NewPage); NewPage.Viewer.Parent := NewPage; AControl.activePage := NewPage; NewPage.Viewer.LoadFromFile(Temp_Dateiname_gl); end; |
AW: Dynamisch erzeugte Komponenten ansprechen
Ach ja, alternativ kann man zusätzlich die wichtigen Komponenten auch noch in Array, TList<>, TDictionary<> oder Dergleichen speichern,
um "direkt" drauf zugreifen zu können, ohne zu suchen. Und ja, und/oder als Komponente oder Frame zusammenfassen, mit passenden Property/Zugriffsfunktionen. |
AW: Dynamisch erzeugte Komponenten ansprechen
Ein simpler class Helper sollte auch gehen.
Da ich keinen TcxTabSheet habe, kann es aber nicht testen.
Delphi-Quellcode:
Wenn sichergestellt ist, dass das erste Control im Tabsheet der Viewer ist.
TTcxTabSheetClassHelper = class Helper for TcxTabSheet
private function GetViewer: TDXPDFViewer; public property Viewer: TDXPDFViewer read GetViewer; end;
Delphi-Quellcode:
Wenn die Positon nicht bekannt ist, werden die Controls durchsucht:
function TTcxTabSheetClassHelper.GetViewer: TDXPDFViewer;
begin Result := Controls[0] as TDXPDFViewer end;
Delphi-Quellcode:
function TTcxTabSheetClassHelper.GetViewer: TDXPDFViewer;
var C: TControl; I: Integer; begin for I := 0 to ControlCount - 1 do begin C := Controls[I]; if C is TDXPDFViewer then Exit(C as TDXPDFViewer); end; Result := nil; end; |
AW: Dynamisch erzeugte Komponenten ansprechen
Bei Controls mußt du aufpassen.
Eine Suche über Components ist da sicherer. Es wurde ja explizit der Owner angegeben und genau in Jenem kann man suchen. DevExpress verschachtelt gern übermäßig oft Komponenten ineinander ... da weißt du garnicht, ob es noch zwischenebenen gibt und ob das Control wirklich (noch) dort liegt. Auch Delphi selbst hat einige Komponenten, wo gern mal der Parent verändert wird. (z.B. TCategoryPanel oder einige Grid-Panels usw.) |
AW: Dynamisch erzeugte Komponenten ansprechen
Danke für die schnellen Anregungen und Hilfe
Habe es jetzt mit Component gemacht:
Delphi-Quellcode:
var
ActiveViewer: TDxPDFViewer; ActiveTab: TcXTabsheet;
Delphi-Quellcode:
procedure TF1.SetActiveViewer;
var i : Integer; begin ActiveTab := PControl.ActivePage; for i := 0 to ActiveTab.ComponentCount - 1 do begin if ActiveTab.Components[i] is TDxPDFViewer then begin ActiveViewer := ActiveTab.Components[i] as TDXPDFViewer; .... end; end; end; |
AW: Dynamisch erzeugte Komponenten ansprechen
Zitat:
Zumindest wird bei Controls alles was TControl der TWinControl ist, berücksichtigt. Ich vermute mal, das alles was bei DevExpress sichbar ist, auch von einem der Beiden abgeleitet wurde. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:25 Uhr. |
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