Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi TListBox zugriffs Problem (https://www.delphipraxis.net/31968-tlistbox-zugriffs-problem.html)

rudi_ 16. Okt 2004 13:04


TListBox zugriffs Problem
 
Hallo,

ich habe gerade ein kleines Problem mit einer TListBox Komponente:
Ich lasse einige einträge aus der Datenbank auslesen und in der ListBox speichern über eine prozedur (vorher wird noch .clear durchgeführt)


jetzt ist aber das problem: ich habe neben meiner form-klasse noch eine weitere eigene klasse.
und wenn ich jetzt aus dieser anderen klassen die prozedure zum füllen der liste aufrufe ("LoadClerks", also FormKlasse.LoadClerks), passiert..... NICHTS

die schleife liest zwar korrekt die zeilen aus der (mysql-) datenbank aus (man kann sich mit showmessage ja das entsprechende feld ausgeben lassen), aber sämtliche routinen der listbox zeigen keine wirkung (items.add, items.clear etc.). Es kommt zwar keine Fehlermeldung, aber es passiert auch nichts.

ich habe schon probiert quasi eine Kopie dieser LoadClerks prozedur in meiner zweiten Klasse zu erstellen und die dann dadrin aufzurufen (sie entspricht der "originalen" prozedur aus der FormKlasse, hat halt nur jeweils anstelle von Listbox.items.... FormKlasse.ListBox.items etc.)


im moment steh ich hier vor ner wand und komm nicht so wirklich weiter :wall:

hoffe mal, dass mir einer helfen kann ;)


gruß rudi




achja: man sollte vieleicht noch sagen, dass die prozedur LoadClerks aus der FormKlasse heraus aufgerufen (z.b. über einen button auf der form) wunderbar funktioniert. Also daran kanns nicht so wirklich liegen dann. meine zweite Klasse ist ein ableger einer TGroupBox und daraus funzt zwar das aufrufen; es passiert halt nur nichts

Gruber_Hans_12345 16. Okt 2004 13:28

Re: TListBox zugriffs Problem
 
zeig mal etwas code

Luckie 16. Okt 2004 13:37

Re: TListBox zugriffs Problem
 
Wird die Prozedur auch azfgerufen? Bist du mal mit F7 Zeile für zeile durchgegangen? Hast du mal BreakPoints gesetzt und dir mal diverse Inhalte von vorkommenden Variablen angekuckt?

Du musst uns schon etwas helfen und das Problem selber etwas eingrenzen, wenn nicht sogar finden. Helfen es zu lösen können wir dir dann. Aber du musst erst mal ein Problem präsentieren. ;)

rudi_ 16. Okt 2004 13:37

Re: TListBox zugriffs Problem
 
das ist zunächst die form:

Delphi-Quellcode:
type
  TSchedClerks = class(TForm)
    btn_ok: TButton;
    lst_clerks: TListBox;
    Button1: TButton;
    procedure btn_okClick(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure lst_clerksClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  private
    FClerkBox: TClerkBox;
    { Private declarations }
  public
    constructor Create(AOwner: TComponent; SchedConfig: TSchedConfig); overload;
    procedure BeforeDestruction; override;
    procedure LoadClerks;
    procedure ClearClerks;
    { Public declarations }
  end;

und das hier ist die Klasse, die zur laufzeit erstellt wird, ein paar daten anzeigt und vor ihrer zerstörung die datenbank aktualisiert (falls was geändert wurde) und dann auch die listbox in der Form aktualisieren soll mit der SchedClerks.LoadClerks Methode

Delphi-Quellcode:
type
  TClerkBox = class(TGroupBox)
    btn_svupd: TButton;
    lbl_clrkcap: TLabel;
    txt_clerkname: TEdit;
  private
    FDataSetID: integer;
    FChanged: boolean;
    procedure SetID(id: integer);
    procedure SetChanged(Sender: TObject);
    procedure UpdateEntry;
    procedure InsertEntry;
    procedure ButtonAction(Sender: TObject);
  public
    property DataSetID: integer
      read FDataSetID write SetID;
    constructor Create(AOwner: TComponent); override;
    procedure BeforeDestruction; override;
end;

und das hier ist die LoadClerks prozedur:
Delphi-Quellcode:
procedure TSchedClerks.LoadClerks;
var
  Result: TResultID;
  Row: TMyRow;
  i: integer;
  Clrk: TStaffObj;
begin
  ClearClerks;
  Result := FMySQL.Query('SELECT * FROM staff ORDER BY name');
  if FMySQL.LastErrorNo = 0 then
  begin
    SetLength(Row,0);
    for i := 0 to FMySQL.AffectedRows(Result)-1 do
    begin
      Row := FMySQL.FetchRow(Result);
      Clrk := TStaffObj.Create;
      clrk.Name := row[1];
      clrk.ID := strtoint(row[0]);
      lst_clerks.Items.AddObject(row[1],clrk);
    end;
  end;
  FMySQL.FreeResult(Result);
end;
das mit dem TStaffObj habe ich eben der einfachheit nicht erwähnt. Weil ich zu jedem Namen auch noch die DatensatzID festhalten will, speicher ich das halt in einem kleinem Objekt in der ListBox

aber selbst wenn ich das sein lasse und nur lst_clerks.Items.Add(row[1]) mache, passiert ja nichts
also kann das keine fehlerursache sein

die prozedur ClearClerks macht nichts, ausser in einer schleife einmal durch die einträge der Listbox zu laufen und die gespeicherten Objekte zu zerstören, bevor ein lst_clerks.Items.Cler aufgerufen wird. (funktionert aber aus demselben grund, warum auch die LoadClerks nicht funktioniert anscheinend nicht)

rudi_ 16. Okt 2004 13:39

Re: TListBox zugriffs Problem
 
@Luckie

ja wie bereits erwähnt lasse ich z.B. die ergebnisse der datenbank ausgeben in einer showmessage in der LoadClerks prozedur
Die Daten werden korrekt ausgelesen, nur sämtliche operationen an der Listbox wie löschen, hinzufügen, ändern etc. zeigen keine wirkung, wenn das aus dem TClerkBox objekt heraus durchgeführt wird

rudi_ 16. Okt 2004 13:47

Re: TListBox zugriffs Problem
 
bevor ich jetzt erstmal weg muss, sollte man ggf. noch erwähnen, dass diese Form aus einer anderen Form heraus mit ShowModal erzeugt wird; falls das wichtig ist:

Delphi-Quellcode:
  ClerkWindow := TSchedClerks.Create(nil,SchedConfig);
  with ClerkWindow do
  begin
    top := (screen.Height div 2) - (height div 2);
    left := screen.Width div 2 - width div 2;
    ShowModal;
  end;
  ClerkWindow.Free;
(das nur am rande)

Gruber_Hans_12345 16. Okt 2004 13:51

Re: TListBox zugriffs Problem
 
wo und wie (und wann) rufst du LoadClerks auf ?

hast du irgendwo BeginUpdate / EndUpdate bei den Items der ListBox ?
(Code von ClearClerks ?)

eventuell eine zweite kopie der Form / ListBox ?

rudi_ 16. Okt 2004 16:49

Re: TListBox zugriffs Problem
 
meinst du mit BeginUpdate/EndUpdate, dass ich quasi das TStrings Objekt (also .Items) der listbox ändere, das ganze aber aus irgendwelchen gründen nicht dargestellst wird? (also quasi geupdated?)


und hier der ClearClerks Code:

Delphi-Quellcode:
procedure TSchedClerks.ClearClerks;
var
  i: integer;
begin
if assigned(FClerkBox) then
begin
  FClerkBox.Free;
  FClerkBox := nil;
end;
for i := 0 to lst_clerks.Count - 1 do
begin
  TStaffObj(lst_clerks.Items.Objects[i]).Free;
end;
lst_clerks.Items.Clear;
end;
wie gesagt, erfüllt seinen zweck, wenn aus der FormKlasse selbst aufgerufen

aber nicht, wenn es aus aus der TClerkBox-Klasse heraus aufgerufen wird


/edit: der teil mit FClerkBox.Free dient nur dazu, eine ggf. angezeigte GroupBox zu schließen. Wobei mir jetzt gerade erst auffällt, dass sich die Klasse ja quasi aus sich selbst heraus abschießen würde. Eine prozedur der Instanz von TClerkBox ruft die methode ClearClerks der Instanz von TSchedClerks (also der form) auf, welche wiederrum eigentlich genau die Instanz der TClerkBox zerstören sollte, die ClearClerks aufgerufen hat.
gibt aber keinen fehler
also entweder bin ich zu 100% ein opfer von "betriebsblindheit" geworden oder ich versteh grad gar nichts mehr *g*

Gruber_Hans_12345 16. Okt 2004 17:00

Re: TListBox zugriffs Problem
 
zeig mal, wo du LoadClerks aufrufst,

übrigens, statt
Delphi-Quellcode:
if assigned(FClerkBox) then
begin
  FClerkBox.Free;
  FClerkBox := nil;
end;
kannst
Delphi-Quellcode:
if assigned(FClerkBox) then FreeAndNil(FClerkBox);
verwenden

rudi_ 16. Okt 2004 17:13

Re: TListBox zugriffs Problem
 
Delphi-Quellcode:
procedure TClerkBox.BeforeDestruction;
begin
if FChanged then
begin
  if FDataSetID <> -1 then
    UpdateEntry
  else
    InsertEntry;
end;
  inherited BeforeDestruction;
end;


procedure TClerkBox.UpdateEntry;
begin
if FChanged then
begin
  FMySQL.Query('UPDATE staff SET name='''+txt_clerkname.Text+''' WHERE id='+inttostr(FDataSetID));
  if FMysql.LastErrorNo <> 0 then
    showmessage(FMySQL.LastErrorMsg);
  FMySQL.FreeResult(FMySQL.LastResultID);
  FChanged := false;
  Caption := 'Information:';
  LoadClerks;
end;
end;

procedure TClerkBox.InsertEntry;
begin
if FChanged then
begin
  FMySQL.Query('INSERT INTO staff (name) VALUES('''+txt_clerkname.text+''')');
  if FMysql.LastErrorNo <> 0 then
    showmessage(FMySQL.LastErrorMsg);
  FMySQL.FreeResult(FMySQL.LastResultID);
  FChanged := false;
  Caption := 'Information:';
  LoadClerks;
end;
end;
zur erklärung der BeforeDestruction methode:
FChanged wird dann auf true gesetzt, wenn jemand den inhalt des textfeldes geändert hat (um nicht unnötig jedesmal einen eintrag zu updaten, der sich gar nicht geändert hat).
FDataSetID speichert den primärschlüssel, um auch den richtigen datensatz in der db zu erwischen
ist FDataSetID = -1, wird angenommen, dass das ganze als neuer Datensatz gespeichert werden soll


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:48 Uhr.
Seite 1 von 2  1 2      

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