Gelöst:Objekte verschieben von einer Listbox zu einer andern

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Eb
Lazarusforum e. V.
Beiträge: 238
Registriert: Di 5. Feb 2008, 15:32
OS, Lazarus, FPC: Linux Mint - Laz 2.2.0
CPU-Target: 64Bit
Wohnort: Stuttgart

Gelöst:Objekte verschieben von einer Listbox zu einer andern

Beitrag von Eb »

Hallo,
Ich bin noch ganz am Anfang mit OOP und würde damit jetzt gerne folgendes umsetzen.
Ich habe zwei Objectlists. Mit beiden wird jeweils eine Listbox gefüllt.

Nun möchte ich in der einen Listbox ein Element selektieren, dann durch klick auf einen Button dieses Element in die andere Listbox verschieben.
Gleichzeitig soll das Element aus der einen Objectlist entfernt und in die andere eingefügt werden.

Das ganze soll in beiden Richtungen funktionieren.

Beim Verschieben des ersten Elements von der Quell- in die Ziel-Listbox scheint alles zu funktionieren, beide Listboxen zeigen den korrekten Inhalt an.
Beim Verschieben des zweiten Elementes scheint auch noch alles zu klappen.

Das Problem kommt hier:
Beim zurückschieben eines Elementes in die Quell-Listbox, kommt das selektierte Element dort nicht an, zudem wird die Ziel-Listbox komplett geleert.

Das Verhalten ist das selbe, ob ich zuerst die linke Listbox fülle (Variante A) oder zuerst die rechte (Variante B)

Ich habe mal ein Minimalbeispiel gebaut:

Code: Alles auswählen

 
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,Contnrs;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    btn_zu_team: TButton;
    btn_zu_fahrer: TButton;
    Label1: TLabel;
    Label2: TLabel;
    ListBox_Fahrer: TListBox;
    ListBox_Team: TListBox;
    procedure btn_zu_fahrerClick(Sender: TObject);
    procedure btn_zu_teamClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    procedure listbox_fahrer_fuellen;
    procedure listbox_team_fuellen;
  end;
 
type
{ TFahrer }
 
 TFahrer = class
 private
 public
   name  : string;
   id    : integer;
 
   constructor Create;
   destructor Destroy;
 
 end;
var
  Form1: TForm1;
 
  ObjectList_Fahrer, ObjectList_Team : TObjectList;
  f1,f2,f3 : TFahrer;
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  close;
end;
 
procedure TForm1.btn_zu_teamClick(Sender: TObject);
var f : TFahrer;
begin
  f := TFahrer.Create;
 
  f := TFahrer(ObjectList_Fahrer[Listbox_Fahrer.ItemIndex]);
 
  // Fahrer in Listbox_Team bringen
  Listbox_Team.AddItem(TFahrer(f).name,f);
 
  // Fahrer in ObjectList_Team bringen
  ObjectList_Team.Add(f);
 
  // Fahrer aus ObjectList_Fahrer entfernen
  ObjectList_Fahrer.Remove(f);
 
  // Listbox_Fahrer neu fuellen
  listbox_fahrer_fuellen;
 
 
end;
 
procedure TForm1.btn_zu_fahrerClick(Sender: TObject);
var f : TFahrer;
begin
  f := TFahrer.Create;
 
  f := TFahrer(ObjectList_Team[Listbox_Team.ItemIndex]);
 
  // Fahrer in Listbox_Fahrer bringen
  Listbox_Fahrer.AddItem(TFahrer(f).name,f);
 
  // Fahrer in ObjectList_Fahrer bringen
  ObjectList_Fahrer.Add(f);
 
  // Fahrer aus ObjectList_Team entfernen
  ObjectList_Team.Remove(f);
 
  // Listbox_Team neu fuellen
  listbox_team_fuellen;
 
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  // Fahrer erzeugen
  f1 := TFahrer.Create;
  f1.name:= 'Fritz';
  f2 := TFahrer.Create;
  f2.name:= 'Hans';
  f3 := TFahrer.Create;
  f3.name:= 'Peter';
 
  // ObjectList_Fahrer erzeugen
  ObjectList_Fahrer := TObjectList.create;
  ObjectList_Fahrer.OwnsObjects := true;
 
 
  // ObjectList_Team erzeugen
  ObjectList_Team := TObjectList.create;
  ObjectList_Team.OwnsObjects := true;
 
 
  // --- Variante A --------  Fahrer in ObjectList_Fahrer bringen
  ObjectList_Fahrer.Add(f1);
  ObjectList_Fahrer.Add(f2);
  ObjectList_Fahrer.Add(f3);
  // --- Ende Variante A ---
 
  {
  // --- Variante B --------  Fahrer in ObjectList_Team bringen
  ObjectList_Team.Add(f1);
  ObjectList_Team.Add(f2);
  ObjectList_Team.Add(f3);
  // --- Ende Variante B ---
  }

 
 
  listbox_fahrer_fuellen;
  listbox_team_fuellen;
 
end;
 
procedure TForm1.listbox_fahrer_fuellen;
var i : integer;
begin
  // Listbox_Fahrer befuellen
  Listbox_Fahrer.Clear;
   if ObjectList_Fahrer.Count > 0 then begin
      for i := 0 to ObjectList_Fahrer.Count - 1 do Listbox_Fahrer.AddItem(TFahrer(ObjectList_Fahrer[i]).name,ObjectList_Fahrer[i]);
       Listbox_Fahrer.ItemIndex:= 0;
  end;
end;
 
procedure TForm1.listbox_team_fuellen;
var i : integer;
begin
  // Listbox_Team befuellen
  Listbox_Team.Clear;
   if ObjectList_Team.Count > 0 then begin
      for i := 0 to ObjectList_Team.Count - 1 do Listbox_Team.AddItem(TFahrer(ObjectList_Team[i]).name,ObjectList_Team[i]);
       Listbox_Team.ItemIndex:= 0;
  end;
end;
 
 
 
{ TFahrer }
 
constructor TFahrer.Create;
begin
 
end;
 
destructor TFahrer.Destroy;
begin
 inherited Destroy;
end;
 
 
end.
 
 


Bin dankbar für alle Tips - bitte mit kurzer Erklärung, da ich es gerne verstehen würde....

Eb
Dateianhänge
objectlist_minimal.zip
(126.9 KiB) 49-mal heruntergeladen
Zuletzt geändert von Eb am Mi 26. Okt 2016, 13:14, insgesamt 1-mal geändert.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Objekte verschieben von einer Listbox zu einer anderen

Beitrag von wp_xyz »

Du hast jeweils eine TObjectList für die Fahrer und für das Team, sowie eine Listbox für die Fahrer und das Team. Das erscheint mir redundant, und dadurch passieren Fehler...

Ich würde nur eine TObjectList verwenden, in der ich alle Fahrer aufliste, egal ob sie im Team sind oder nicht. Solange kein neuer Fahrer dazukommt oder ein bisheriger ausscheidet, wird an dieser nichts mehr verändert.

Die Listbox für die Fahrer würde ich dann mit allen Items der ObjectList füllen, und zwar nicht mit Listbox.Add, sondern mit Listbox.AddObject - dieser Methode kannst du nämlich einen Zeiger auf den Fahrer mitgeben. Die Listbox für das Team ist anfangs leer.

Code: Alles auswählen

for i:=0 to ObjectList_Fahrer.Count-1 do
  begin
    f := TFahrer(ObjectList_Fahrer[i]);
    Lisbox_Fahrer.Items.AddObject(f.Name, f);
  end;

Wenn ein fahrer ins Team überwechselt, wird dieser aus Listbox_Fahrer gelöscht - dabei ist wichtig, dass dabei das Objekt (der fahrer) nicht zerstört wird. Man muss sich also vorher den Fahrer merken und kann ihn dann in die ListBox_Team hinzufügen:

Code: Alles auswählen

  if Listbox_Fahrer.ItemIndex > -1 then begin
    f := TFahrer(Listbox_Fahrer.Items.Objects[Listbox_Fahrer.ItemIndex]);
    Listbox_Fahrer.Items.Delete(Listbox_Fahrer.ItemIndex);
    Listbox_Team.Items.Add(f.Name, f);
  end;

Wenn ein fahrer aus dem Team herausgenommen wird, geht's genauso, nur sind die Bezüge auf "Fahrer" und "Team" vertauscht:

Code: Alles auswählen

  if Listbox_Team.ItemIndex > -1 then begin
    f := TFahrer(Listbox_Team.Items.Objects[Listbox_Team.ItemIndex]);
    ListBox_Team.Items.Delete(Listbox_Team.ItemIndex);
    Listbox_Fahrer.items.Add(f.Name, f);
  end;

Eb
Lazarusforum e. V.
Beiträge: 238
Registriert: Di 5. Feb 2008, 15:32
OS, Lazarus, FPC: Linux Mint - Laz 2.2.0
CPU-Target: 64Bit
Wohnort: Stuttgart

Re: Objekte verschieben von einer Listbox zu einer anderen

Beitrag von Eb »

Funktioniert perfekt.

Vielen Dank !!
Gruß Eb

Antworten