TListView Probleme beim Selektieren

Für Fragen von Einsteigern und Programmieranfängern...
jscnetcore
Beiträge: 19
Registriert: Mi 31. Jul 2013, 11:34
OS, Lazarus, FPC: Debian Squeeze Linux (L 1.0.8 FPC 2.6.2)
CPU-Target: 32Bit

TListView Probleme beim Selektieren

Beitrag von jscnetcore »

Wenn ich ein TListView mit Items fülle und zum Schluß das erste Item mit

Code: Alles auswählen

 
List.Items.Item[0].Selected := true; 
 
selektiere funktioniert soweit alles. Das Item wird blau hinterlegt und ist somit markiert.

Wenn ich jetzt irgendein anderes Item auswähle funktioniert das beim ersten mal nicht.
OnSelectItem wird ausgeführt aber es wird das erste Item übergeben (Item[0]), nicht das aktuell ausgewählte.
Bei allen weiteren Versuchen funktionert das.
Wenn ich das ganze mache ohne das erste Item automatsich mit o.g. Code zu selektieren funktioniert das auf Anhieb.

Hat jemand eine Idee was da falsch läuft?

Falls gewüscht kann ich euch auch meinen kompletten Code hier einstellen.

Gruß Josch

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: TListView Probleme beim Selektieren

Beitrag von Michl »

Ich weiss nicht bei mir geht das.

Habe mal zu Testzwecken eine TListView auf eine leere Form gezogen und beim OnCreate der Form folgenden Code eingegeben:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
var
  x:integer;
begin
  for x:=0 to 19 do begin
    ListView1.Items.Add;
    ListView1.Items[x].Caption:='Item No ['+inttostr(x)+']';
  end;
  ListView1.Items[8].Selected:=true;
end;  
... das funktioniert, Item[8] wird selektiert (blau hinterlegt).

Ich nutze L1.1 FPC 2.7.1 Win32, welche Lazarusversion bzw. OS nutzt du?!

[Edit] eben noch bei L1.0.10 FPC 2.6.2 Win32 getestet - geht auch!

[Edit] Was mir noch einfällt ist, dass die TListView evtl. nicht den Focus hat, das könntest du mit

Code: Alles auswählen

procedure TForm1.FormActivate(Sender: TObject);
begin
  ListView1.SetFocus;
end;  
noch machen. Evtl. reicht dir aber auch "ListView1.HideSelction:=false;"?!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

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

Re: TListView Probleme beim Selektieren

Beitrag von wp_xyz »

Bin nicht ganz sicher, aber deinen Zugriff würde ich nehmen, wenn bei MultiSelect = true mehrere Items ausgewählt werden sollen. Um - wie üblich - nur ein Item auszuwählen, sollte folgendes funktionieren:

Code: Alles auswählen

 
  Listview.Selected := Listview.Items[2];
 

jscnetcore
Beiträge: 19
Registriert: Mi 31. Jul 2013, 11:34
OS, Lazarus, FPC: Debian Squeeze Linux (L 1.0.8 FPC 2.6.2)
CPU-Target: 32Bit

Re: TListView Probleme beim Selektieren

Beitrag von jscnetcore »

Guten Morgen,

danke schon mal euch beiden!
Ich habe alle eure Tips ausprobiert funktioniert aber beides leider nicht.

Der einzige unterschied zwischen

Code: Alles auswählen

ListView1.Items[8].Selected:=true;
und

Code: Alles auswählen

Listview.Selected := Listview.Items[8];
ist, dass beidem zweitgenannten das OnSelectItem Event beim Start ausgelöst wird.

Ich habe beim OnSelectItem Event folgendes eingetragen

Code: Alles auswählen

showmessage('ListSelectItem  ' + inttostr(Item.Index));


Und egal welches andere Item ich nach dem Start anklicke, es wird beim ersten mal immer die '8' angezeigt?!

Wenn ich das Programm starte werden die 19 Elemente erzeugt, das 8. wird selektiert und blau hinterlegt. Das 19. Element erhält einen grauen, gestrichelten Rand.
Wenn ich mit den Pfeiltasten navigiere geht alles vom 19. Element aus.

Anmerkung
Ich benutze die ListView -> ViewStyle vsIcon !!


Hab das ganze mal zum Spaß auf vsList umgestellt. da wirds ganz kurios

Code: Alles auswählen

Listview1.Selected := Listview1.Items[8];
funktioniert gar nicht.
Und egal auf welches Element ich klicke der OnSelectItem Event wird zich mal ausgelöst?

Ich benutze Debian Squeeze, Lazarus 1.0.8, FPC 2.6.2, i386-linux-gtk 2

Zum Hintergrund des ganzen. Ich möchte mir aus einem Ordner alle Bilder als Icon verkleinert darstellen lassen wobei das erste Bildchen automatisch selektiert werden soll.
Dieses automatisch selektierte Bildchen wir mir in einem anderen Bereich des Programms in Originalgröße angezeigt.
Dann möchte ich mit gedrückter Strg Taste weitere Bilder auswählen und das haut beim ersten Click nicht hin. Das ausgewählte Element schreibe ich sofort in eine StrigList, die
ich später abarbeiten möchte. Das erste automatisch ausgewählte Element steht zweimal drin, einmal von der automatischen Selektion her und einmal von mir manuell, egal auf welches Element ich als erstes klicke :x

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: TListView Probleme beim Selektieren

Beitrag von Michl »

Wenn ich das Programm starte werden die 19 Elemente erzeugt, das 8. wird selektiert und blau hinterlegt. Das 19. Element erhält einen grauen, gestrichelten Rand.
Wenn ich mit den Pfeiltasten navigiere geht alles vom 19. Element aus.
Ich denke, dann ging es dir nicht darum ein Item auszuwählen, sondern den Focus auf dieses zu setzen. Probier mal:

Code: Alles auswählen

procedure TForm1.FormActivate(Sender: TObject);
begin
  ListView1.Selected:=ListView1.Items[8];
  ListView1.ItemFocused:=ListView1.Items[8];
  ListView1.SetFocus;
end; 
Weitere Infos der TCustomListView unter http://lazarus-ccr.sourceforge.net/docs ... tview.html bzw. Eigenschaften der abgeleiteten TListView unter http://lazarus-ccr.sourceforge.net/docs ... tview.html
Zuletzt geändert von Michl am Do 5. Sep 2013, 09:23, insgesamt 1-mal geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: TListView Probleme beim Selektieren

Beitrag von Michl »

jscnetcore hat geschrieben:Und egal auf welches Element ich klicke der OnSelectItem Event wird zich mal ausgelöst?
Ich hab´s mal getestet und folgenden Code geschrieben:

Code: Alles auswählen

procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
const
  Zaehler:integer=0;
begin
  inc(Zaehler);
  Caption:='OnSelect wurde insgesamt '+inttostr(Zaehler)+' mal aufgerufen, gewähltes Item ist ['+Item.Caption+']';
end; 
Es scheint so, dass SelectItem immer 2 mal aufgerufen wird. Warum, weiss ich nicht, bist aber nicht der Erste, der das feststellt, siehe: http://www.lazarusforum.de/viewtopic.php?f=18&t=3714 oder hier: http://forum.lazarus.freepascal.org/ind ... ic=19762.0

Weiss nicht, ob das ein Bug ist und dieser reportet werden sollte?!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

jscnetcore
Beiträge: 19
Registriert: Mi 31. Jul 2013, 11:34
OS, Lazarus, FPC: Debian Squeeze Linux (L 1.0.8 FPC 2.6.2)
CPU-Target: 32Bit

Re: TListView Probleme beim Selektieren

Beitrag von jscnetcore »

Bei ViewStyle -> vsList

Nach dem Start
OnSelect wurde insgesamt 1 mal aufgerufen, gewähltes Item ist 8
Klick auf Item 0
OnSelect wurde insgesamt 21 mal aufgerufen, gewähltes Item ist 19
Klick auf Item 2
OnSelect wurde insgesamt 23 mal aufgerufen, gewähltes Item ist 0
Klick auf Item 4
OnSelect wurde insgesamt 25 mal aufgerufen, gewähltes Item ist 2

Bei ViewStyle -> vsIcon
Nach dem Start
OnSelect wurde insgesamt 1 mal aufgerufen, gewähltes Item ist 8
Klick auf Item 12
OnSelect wurde insgesamt 2 mal aufgerufen, gewähltes Item ist 8
Klick auf Item 9
OnSelect wurde insgesamt 3 mal aufgerufen, gewähltes Item ist 9
... danach passt alles !!!!

Eigentlich müsste ich es hier nur hinbekommen den ersten Select zweimal abzusetzen und quasi den ersten einfach ingnorieren :wink:

Ich werde das mal auf meinem Fenster Klapprechner ausprobieren, mal schauen wie es sich dort verhält

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

Re: TListView Probleme beim Selektieren

Beitrag von wp_xyz »

OnSelected wird - meiner Meinung nach - bewusst zweimal aufgerufen, einmal, wenn der bisher ausgewählte Eintrag die Markierung verliert, und einmal wenn der neue Eintrag die Markierung bekommt. Deshalb gibt es ja den Parameter "Selected". Wenn man ihn abfragt, kann man die Weiterverarbeitung auf den Vorgang des Auswählens beschränken.

Das gilt für Windows, zu Linux kann ich nichts sagen. Will nicht abstreiten, dass sich die die Listview da anders verhalten kann.

Ansonsten würde ich für eine Bildervorschau statt einer Listview theo's Thumbnail Viewer (http://www.lazarusforum.de/viewtopic.ph ... iew#p58129) empfehlen.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: TListView Probleme beim Selektieren

Beitrag von Michl »

jscnetcore hat geschrieben:Bei ViewStyle -> vsList

Nach dem Start
OnSelect wurde insgesamt 1 mal aufgerufen, gewähltes Item ist 8
Klick auf Item 0
OnSelect wurde insgesamt 21 mal aufgerufen, gewähltes Item ist 19
Klick auf Item 2
OnSelect wurde insgesamt 23 mal aufgerufen, gewähltes Item ist 0
Klick auf Item 4
OnSelect wurde insgesamt 25 mal aufgerufen, gewähltes Item ist 2

Bei ViewStyle -> vsIcon
Nach dem Start
OnSelect wurde insgesamt 1 mal aufgerufen, gewähltes Item ist 8
Klick auf Item 12
OnSelect wurde insgesamt 2 mal aufgerufen, gewähltes Item ist 8
Klick auf Item 9
OnSelect wurde insgesamt 3 mal aufgerufen, gewähltes Item ist 9
... danach passt alles !!!!

Eigentlich müsste ich es hier nur hinbekommen den ersten Select zweimal abzusetzen und quasi den ersten einfach ingnorieren :wink:

Ich werde das mal auf meinem Fenster Klapprechner ausprobieren, mal schauen wie es sich dort verhält
Nö, kann ich nicht bestätigen, wird immer 2 mal aufgerufen!
wp_xyz hat geschrieben:OnSelected wird - meiner Meinung nach - bewusst zweimal aufgerufen
Macht für mich absolut keinen Sinn, ist bei anderen Komponenten ja auch nicht so. Will man den Vorgänger haben, dann könnte man sich den ja selber in einer Variable speichern. Regelwidrig ist es auf jeden Fall, wenn sich das Verhalten bei der Ansicht (vsList/vsIcon), obwohl ich das nicht reproduzieren kann, verändert!

Ich habe mal einen Bug-Report gemacht, mal sehen...

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

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

Re: TListView Probleme beim Selektieren

Beitrag von wp_xyz »

@jscnetcore: Und wenn du den Parameter "Selected", der dem Event mitgegeben wird, auswertest (if Selected ....), ist das Verhalten noch genauso?

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: TListView Probleme beim Selektieren

Beitrag von Michl »

Da hast du recht bei

Code: Alles auswählen

procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
const
  Zaehler:integer=0;
begin
  if Selected then inc(Zaehler);
  Caption:='OnSelect called '+inttostr(Zaehler)+' times';
end; 
wird ordentlich gezählt, zumindest bei mir.

Dieses Verhalten ist trotzdem komisch, nehme ich z.B. eine Stringgrid (ist zwar ein Apfel-Birne-Vergleich), dort wird OnSelectCell ja auch nur ein mal aufgerufen. Daher macht dieses Verhalten für mich eigentlich keinen Sinn :? .

[Edit] Ok, habe jetzt mal einen BreakPoint gesetzt und mir den jeweiligen ItemIndex angesehen. Das erste mal steht der ItemIndex bei -1, das zweite Mal bei dem gewählten Item. Das ist in meinen Augen ein Bug!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

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

Re: TListView Probleme beim Selektieren

Beitrag von wp_xyz »

Bug oder nicht Bug? Die Antwort wird wahrscheinlich sein: Delphi macht's auch so.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: TListView Probleme beim Selektieren

Beitrag von Michl »

wp_xyz hat geschrieben:Bug oder nicht Bug? Die Antwort wird wahrscheinlich sein: Delphi macht's auch so.
... ja wahrscheinlich!

habe noch probiert von außen per Button mal das Item zu setzen:

Code: Alles auswählen

ListView1.Items[random(ListView1.Items.Count)].Selected:=true;
Bei Multiselect=False wird OnSelectItem zwei mal aufgerufen!
bei Multiselect=True wird OnSelectItem nur einmal aufgerufen!

Könnte also ein Feature von Multiselect sein...

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: TListView Probleme beim Selektieren

Beitrag von Michl »

Nach den Posts im Bug-Tracker ist das Verhalten gewollt...

Wahrscheinlich liegt es daran, dass man für das Unselektieren kein separates Ereignis erstellen wollte. Daher hat man sich so beholfen, dass man den Parameter Selected übergibt.

Also:
1. Aufruf -> unselect
2. Aufruf -> neues selectiertes Item

Das erklärt auch das Verhalten von meinen vorherigem Post!

Bestätigt deine Aussage:
wp_xyz hat geschrieben:OnSelected wird - meiner Meinung nach - bewusst zweimal aufgerufen, einmal, wenn der bisher ausgewählte Eintrag die Markierung verliert, und einmal wenn der neue Eintrag die Markierung bekommt. Deshalb gibt es ja den Parameter "Selected".
... kein Bug sondern ein Feature, naja vielleicht braucht man´s ja mal :) .

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

jscnetcore
Beiträge: 19
Registriert: Mi 31. Jul 2013, 11:34
OS, Lazarus, FPC: Debian Squeeze Linux (L 1.0.8 FPC 2.6.2)
CPU-Target: 32Bit

Re: TListView Probleme beim Selektieren

Beitrag von jscnetcore »

.... Nö, kann ich nicht bestätigen, wird immer 2 mal aufgerufen!

So, ich habe das ganze mal zum Testen unter Windows 7, Lazarus Version 1.0.6 versucht und ich muss Michl recht geben.
Das Event wird ausser beim ersten mal immer 2 mal aufgerufen, egal ob vsIcon oder vsList.

Unter Linux verhält sich das definitiv anders, hab keine Ahnung warum :cry:
Ich habe das ganze auch mal unter Kubuntu, Lazarus 0.9.irgendwas versucht, geht auch nicht.

Da werde ich wohl weiter suchen müssen bzw. mir wirklich was zurechtbasteln müssen?!

Antworten