Einzelnen Beitrag anzeigen

Jürgen Thomas

Registriert seit: 13. Jul 2006
Ort: Berlin
750 Beiträge
 
#2

Re: Komponenten löschen > Abstracter Fehler

  Alt 26. Aug 2006, 18:23
Hallo Michael,

zunächst einmal zu Deiner eigentlichen Frage.
Zitat von mimi:
und zwar über einen button der dieser komonente gehört.
Bedeutet das, dass der betreffende Button auf dem Panel liegt? Dann müsstest Du eigentlich auch den Button zur Laufzeit erzeugen und dem Panel zuordnen:
Button23.Parent := Panel23; // oder so Wenn der Button anders erzeugt wurde, dann sollte Dein Verfahren im Prinzip richtig sein. Versuche einmal, genaue Prüfungen einzubauen, Haltepunkt auf begin setzen und dann im Einzelschritt zu debuggen:
Delphi-Quellcode:
procedure TForm2.PanelFree(Sender:Tobject);
// da du ein Panel löschen willst, kann Du es auch so deklarieren
var test: TPanel;
begin
  // ist der Sender wirklich ein Button?
  if (Sender is TButton) then
  begin
    // sitzt der Button auf einem Panel?
    if (Sender as TButton).Parent is TPanel then
    begin
      // da Du das Control hinter der Variable test löschen willst, muss es
      // erst einmal zugeordnet werden!!! das fehlte bei Dir auf jeden Fall,
      // oder es kam zu spät, als Button.Parent bereits auf nil gesetzt wurde
      test := (Sender as TButton).Parent as TPanel;
      // entferne die Verknüpfung des Buttons von seinem Parent
      // Dein Fehler hier war wahrscheinlich das doppelte Parent
      (Sender as TButton).Parent := nil;
      // jetzt kannst Du das Panel auflösen, aber bitte mit Fehlerprüfung
      try
        test.free;
      except
        ; // leere Fehlermaßnahme funktioniert und genügt hier wohl
      end;
    end;
  end;
end;
Wenn der Button zur Laufzeit erzeugt wurde, muss er ebenfalls 'manuell' gelöscht werden. Das darf aber keinesfalls innerhalb seiner eigenen OnClick-Routine (PanelFree?) geschehen; denn dann würde der Sender während der Ausführung verschwinden, und das Programm wüsste am Ende von PanelFree nicht mehr, was es mit den Variablen und Daten auf dem Stack anfangen soll!

Wenn der Button durch Add_PlaylistPanel erzeugt wurde (worauf Deine Variable sp:TJvBitBtn hindeutet), musst Du völlig anders verfahren:
1. ButtonClick muss ebenso wie oben prüfen, ob es sich um einen Button auf einem Panel handelt.
2. Eine Variable des Formulars muss eine Information erhalten:
sPanel_soll_geloescht_werden := ((Sender as TButton).Parent as TPanel).Name; 3. Der Focus muss vom Panel wegbewegt werden!!!
StaticText1.SetFocus; // ich bin mir nicht sicher, ob das bei TStaticText möglich ist 4. Dieses Control prüft, ob die Löschung jetzt möglich und vorgesehen ist:
Delphi-Quellcode:
// OnEnter des neuen Controls prüft:
if sPanel_soll_geloescht_werden <> 'then
begin
  // Panel löschen, ähnlich wie oben, aber als Parameter eher den Namen übergeben;
  // denn der Sender hat jetzt keine Bedeutung mehr
  // 1. suche unter allen Komponenten diejenige mit dem übergebenen Namen
  // 2. lösche alle Komponenten, die auf diesem Panel setzen
  // 3. lösche das Panel selbst
  // Variable zurücksetzen
  sPanel_soll_geloescht_werden := '';
end;
Ich hoffe, diese Hinweise helfen Dir weiter.

Zusatzbemerkungen
1. Wo ist Add_PlaylistPanel deklariert? innerhalb von TForm1, von TForm2 oder global? Sinnvollerweise gehört es in das Formular, in dem die Panels erzeugt werden. Nur wenn Du dies in mehreren Formularen erledigst, ist eine globale Deklaration (unter Win32 - nicht unter NET) sinnvoll.

2. Was hat 'Form1.Show' in dieser Prozedur zu suchen? Wenn es darum geht, dass das Panel angezeigt wird, dann benutze am Ende dieser Routine:
ScrollBox.Refresh; 3. Die Variable 'str' beim Erstellen des Panels ist überflüssig; eine Konvertierung StrToInt/IntToStr kann eingespart werden:
Delphi-Quellcode:
  Panel.tag := form1.JvPageControl1.PageCount * 10 + ScrollBox.ControlCount-1;
  panel.name := 'Panel' + IntTostr(Panel.tag);
Ich finde auch, dass Leerzeichen vor und hinter ':=' das Ganze besser lesbar machen.

PS. In letzter Zeit sind Deine Beiträge verständlich. Danke für diese Rücksichtnahme!
#D mit C# für NET, dazu Firebird
früher: Delphi 5 Pro, Delphi 2005 Pro mit C# (also NET 1.1)
Bitte nicht sauer sein, wenn ich mich bei Delphi-Schreibweisen verhaue; ich bin inzwischen an C# gewöhnt.
  Mit Zitat antworten Zitat