AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi FMX: Seltsames Verhalten beim Entfernen von ListboxItems

FMX: Seltsames Verhalten beim Entfernen von ListboxItems

Ein Thema von Sherlock · begonnen am 6. Jan 2017 · letzter Beitrag vom 9. Jan 2017
Antwort Antwort
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.762 Beiträge
 
Delphi 11 Alexandria
 
#1

FMX: Seltsames Verhalten beim Entfernen von ListboxItems

  Alt 6. Jan 2017, 09:39
Hi,

ich hätte da gerne wieder mal ein Problem mit FMX unter Berlin 1.2. Man nehme:
  • Ein neues plattformübergreifendes Projekt
  • Auf das Formular kommen zwei TButtons und eine TListBox
  • Ein Button wird AddBtn genannt, der andere RemoveBtn
  • Dann ergänze man den Code wie im folgenden gezeigt
Delphi-Quellcode:
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
  FMX.ListBox, FMX.Controls.Presentation, FMX.StdCtrls;

type
  TForm1 = class(TForm)
    AddBtn: TButton;
    ListBox1: TListBox;
    RemoveBtn: TButton;
    procedure AddBtnClick(Sender: TObject);
    procedure DelBtnClick(Sender: TObject);
    procedure RemoveBtnClick(Sender: TObject);
  private
    {Private-Deklarationen}
  public
    {Public-Deklarationen}
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}


procedure TForm1.AddBtnClick(Sender: TObject);
var
  myListItem : TListBoxItem;
  myDelBtn : TSpeedButton;
begin
  myListItem := TListBoxItem.Create(ListBox1);
  myListItem.Parent := ListBox1;

  myDelBtn := TSpeedButton.Create(myListItem);
  myDelBtn.Parent := myListItem;
  myDelBtn.Width := 50;
  myDelBtn.Align := TAlignLayout.Right;
  myDelBtn.StyleLookup := 'trashtoolbuttonbordered';
  myDelBtn.OnClick := DelBtnClick;
end;

procedure TForm1.RemoveBtnClick(Sender: TObject);
begin
  if ListBox1.Count > 0 then
  begin
    ListBox1.ListItems[0].Free;
  end;
end;

procedure TForm1.DelBtnClick(Sender: TObject);
begin
  if TFmxObject(Sender).Parent is TListBoxItem then
  begin
    TListBoxItem(TFmxObject(Sender).Parent).IsSelected := True;
    ListBox1.Selected.Free;
    ListBox1.ItemIndex := -1;
  end;
end;

end.
Als Ergebnis kann man mit dem AddBtn Einträge in die Listbox hinzufügen, und mit dem RemoveBtn den jeweils obersten löschen. Das funktioniert wunderbar. In der Listbox gibt es aber netterweise noch einen weiteren Button pro Eintrag, mit dem gezielt dieser Eintrag entfernt werden kann. Wenn man das nutzt ist scheinbar auch alles in Butter, ABER die Titelleiste der Appilikation reagiert dann erst wieder auf Mausklicks, wenn man eine der Komponenten anklickt.
  1. Kann das jemand nachvollziehen?
  2. Weiss jemand wie man das korrigieren kann?

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.896 Beiträge
 
Delphi 12 Athens
 
#2

AW: FMX: Seltsames Verhalten beim Entfernen von ListboxItems

  Alt 6. Jan 2017, 12:43
Nicht getestet, aber ich würde auch die Events löschen.

Delphi-Quellcode:
procedure TForm1.RemoveBtnClick(Sender: TObject);
begin
  if ListBox1.Count > 0 then
  begin
    // So inder Art ...
    btn := ListBox1.ListItems[0].FindSpeedButton; // Müsste man in den Child-Compoents suchen ...
    btn.OnClick := nil;
    btn := nil;
    ListBox1.ListItems[0].Free;
  end;
end;
Damit nicht ein Event auf ein gelöschtes Control gefeuert wird.

Rollo
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.762 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: FMX: Seltsames Verhalten beim Entfernen von ListboxItems

  Alt 6. Jan 2017, 14:49
Hmmm, ich verabschiede mich gerade in meiner eigentlichen Implementierung von der Löschen-Idee und möchte die Einträge einfach immer drin lassen (ist eine zur Laufzeit bestimmte fixe Anzahl).

Mich interessiert dennoch, ob das Verhalten ein Bug ist, oder mein Fehler. Im ersteren Fall würde ich einen Report machen, in letzterem wäre ich für Aufklärung dankbar.

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.896 Beiträge
 
Delphi 12 Athens
 
#4

AW: FMX: Seltsames Verhalten beim Entfernen von ListboxItems

  Alt 6. Jan 2017, 15:07
Kann ich mir nicht vorstellen.
Ich mache das zwar nicht so wie in deinem Beispiel, auch nicht mit TButtons, aber ich benutze andere, auch komplexere Komponenten wie TLayout, TImage, TRectangle, etc. als Child-Komponenten ohne Probleme.

Rollo
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
961 Beiträge
 
Delphi 6 Professional
 
#5

AW: FMX: Seltsames Verhalten beim Entfernen von ListboxItems

  Alt 6. Jan 2017, 17:01
Hmm..

Kenne zwar nur VCL, aber, Du machst IM BtnClick ein Free des Buttons selber, somit können events, welche NACH dem BtnCLick noch kommen könnten gegen einem nicht mehr vorhandenen Button laufen.

Unter VCL würde ich im BtnClick NUR ein PostMessage absetzen mit dem Index des Eintrages und dann in der Behandlungsroutine den ListBoxEntry löschen.
So ist sichergestellt, dass alle noch zum BtnClick gehöhrenden Events abgearbeitet sind, bevor der Btn selber gelöscht wird.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: FMX: Seltsames Verhalten beim Entfernen von ListboxItems

  Alt 6. Jan 2017, 17:13
gibt es kein BtnUp?
wäre wohl am ehesten dafür geeignet den btn auf NIL zu setzen.

gruss
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.477 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: FMX: Seltsames Verhalten beim Entfernen von ListboxItems

  Alt 6. Jan 2017, 22:46
Hmm..

Kenne zwar nur VCL, aber, Du machst IM BtnClick ein Free des Buttons selber, somit können events, welche NACH dem BtnCLick noch kommen könnten gegen einem nicht mehr vorhandenen Button laufen.

Unter VCL würde ich im BtnClick NUR ein PostMessage absetzen mit dem Index des Eintrages und dann in der Behandlungsroutine den ListBoxEntry löschen.
So ist sichergestellt, dass alle noch zum BtnClick gehöhrenden Events abgearbeitet sind, bevor der Btn selber gelöscht wird.
Ja, genau das ist der Grund, das aufrufende Objekt wird zerstört, bevor das Event, das es ausgelöst hat, abgearbeitet wurde.

Die hier beschriebene Lösungs-Variante mit Postmessage ginge natürlich nur unter Windows. Es ginge aber das allgemeine Messaging (TmessageManager) oder man macht es z.B. so:

Delphi-Quellcode:
procedure TForm46.DelBtnClick(Sender: TObject);
var
  lbi: TListBoxItem;
begin
  if TFmxObject(Sender).Parent is TListBoxItem then
  begin
    lbi := TListBoxItem(TFmxObject(Sender).Parent);
    lbi.IsSelected := True;

    TTask.run (procedure
    begin
      TThread.Synchronize(NIL, procedure
        begin
          lbi.free;
          ListBox1.ItemIndex := -1;
      end);
    end);
  end;
end;
TTask.Run wird erst nach Beendigung des Klick-Events ausgeführt, dann kann man gefahrlos das Objekt zerstören.

Geändert von Harry Stahl ( 7. Jan 2017 um 13:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.762 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: FMX: Seltsames Verhalten beim Entfernen von ListboxItems

  Alt 9. Jan 2017, 06:47
Ah, Klasse. Danke Harry. Hab zwar das Bedienkonzept geändert, aber als "Grundlagenwissen" ist das viel Wert. Danke an alle.

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:59 Uhr.
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