Delphi-PRAXiS

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 Listview von doppelten Einträgen befreien. (https://www.delphipraxis.net/55732-listview-von-doppelten-eintraegen-befreien.html)

padavan 26. Okt 2005 05:28


Listview von doppelten Einträgen befreien.
 
Moin Leute,
hat jemmand ne Idee wie man ´ne Listview von doppelten Einträgen befreien könnte?
Wobei nur die in der ersten Spalte relevant sind listivew.items[].caption, nicht die Subitems,
wohl aber sind oder könnten welche vorhanden sein. Und genau da liegt das Problem, denn evtl. vorhandene Subitems werden nicht mehr zurückgeschrieben.


Hab´s mal so versucht

Delphi-Quellcode:
procedure TForm1.Doppelkiller(Listview: TListview);
var
   i: integer;
   lTempList: TStringList;
begin
  screen.Cursor := crhourglass;
  if (Listview <> nil) then begin
    lTempList := TStringList.Create;
    try
      Listview.Items.BeginUpdate;
      try
        for i := 0 to Listview.Items.Count - 1 do
          if (lTempList.IndexOf(Listview.Items[i].Caption) = -1) then //IndexOf liefert -1 wenn nicht gefunden
        lTempList.Add(Listview.Items[i].Caption);
        Listview.Items.Clear;
        for i := 0 to lTempList.Count - 1 do begin
          listview.Items.Add;
          Listview.Items[i].Caption := lTempList[i];
        end;
      finally
        Listview.Items.EndUpdate;
      end;
    finally
      lTempList.Free;
      screen.Cursor := crdefault;
    end;
  end;
end;



//aufruf
  Doppelkiller(Listview);
Hab versucht den Code entsprechend zu ergänzen, wollte aber einfach nicht gelingen.
Nachdem ich dann auch auf andere Art und Weise (zwei gegenläufige Schleifen) nicht weiterkam, nerve ich euch jetzt damit...
:lol:

Danke schonmal

(PS: der code stammt im Original von hier, allerdings für Listbox1)

chaosben 26. Okt 2005 05:50

Re: Listview von doppelten Einträgen befreien.
 
Probiers mal damit:
Delphi-Quellcode:
procedure TForm4.Doppelkiller(LV: TListview);
var
  slItems : TStrings;
  idx : Integer;
begin
  if (not Assigned(LV)) then
    exit;
  try
    slItems:=TStringList.Create;
    Lv.Items.BeginUpdate;
    for idx:=LV.Items.Count-1 downto 0 do
    begin
      if (slItems.IndexOf(LV.Items.Item[idx].Caption)=-1) then
        slItems.Add(LV.Items.Item[idx].Caption)
      else
        LV.Items.Delete(idx);
    end;
    Lv.Items.EndUpdate;
  finally
    slItems.Free;
  end;
end;

padavan 26. Okt 2005 06:10

Re: Listview von doppelten Einträgen befreien.
 
Hey Super - sehr elegant,

vielen Dank !!!

:-D

chaosben 26. Okt 2005 06:29

Re: Listview von doppelten Einträgen befreien.
 
:-D

marabu 26. Okt 2005 06:46

Re: Listview von doppelten Einträgen befreien.
 
Hallo ihr beiden, zwei Dinge hätte ich noch.

Zum einen macht es mich stutzig, dass ein Löschen bei gleicher Caption und differierenden SubItems nicht verlustfrei ist - eventuell vorhandene SubItems sollten doch gerettet werden, oder habe ich das falsch verstanden?

Und zum anderen dient eine ListView der Visualisierung und ist kein Datenspeicher. Hier eine alternative Vorgehensweise beim Einsatz einer virtuellen ListView. Nehmen wir an, die Daten wären in einer StringList gespeichert und die Zeilen hätten folgenden Aufbau:
Code:
Caption1=SubItem1,SubItem2,SubItem3
Dann kann man sie folgendermaßen löschen:
Delphi-Quellcode:
procedure LootSubItems(s: TStrings; iFrom, iTo: integer);
var
  i: integer;
  sFrom, sTo: TStrings;
begin
  sFrom := TStringList.Create;
  sFrom.CommaText := s.Values[s.Names[iFrom]];
  sTo := TStringList.Create;
  sTo.CommaText := s.Values[s.Names[iTo]];
  for i := 0 to Pred(sFrom.Count) do
    if sTo.Count <= i then
      sTo.Add(sFrom[i])
    else if sFrom[i] <> '' then
      sTo[i] := sFrom[i];
  s.Values[s.Names[iTo]] := sTo.CommaText;
  sFrom.Free;
  sTo.Free;
end;

procedure KillDuplicates(s: TStrings);
var
  iLow, iHigh: integer;
begin
  for iLow := 0 to s.Count - 2 do
    for iHigh := Pred(s.Count) downto Succ(iLow) do
      if s.Names[iLow] = s.Names[iHigh] then
      begin
        LootSubItems(s, iHigh, iLow)
        s.Delete(iHigh);
      end;
end;
Grüße vom marabu

chaosben 26. Okt 2005 06:52

Re: Listview von doppelten Einträgen befreien.
 
Hi marabu,

ja klar ist deine Lösung die "schönere" (in "" weil: was ist wenn die SubItems Kommata beinhalten?).
Was die verlorenen Subitems angeht: Die kamen durch das "Items.Clear" zustande und weil danach ja nur die Captions als Items wieder eingefügt wurden. Das Übergehen der Subitems in meinem Beispiel beruht auf folgender Aussage:
Zitat:

Wobei nur die in der ersten Spalte relevant sind listivew.items[].caption, nicht die Subitems
Aber was erzähl ich dir ... das weißt du ja auch so! :stupid: ;)

marabu 26. Okt 2005 07:05

Re: Listview von doppelten Einträgen befreien.
 
Hallo Benjamin,

ich bin hier außer Konkurrenz am Start. Da padavan sein Programm wahrscheinlich nicht umstellen möchte, ist deine Lösung ja okay. Ich will nur gebetsmühlenartig darauf hinweisen, dass niemand eine visuelle Komponente als Datenspeicher missbrauchen muss. Und die Kommata in den SubItems - probiere es mal aus. Du wirst dich wundern, wie schön und standardmäßig das von TStringList behandelt wird.

Freundliche Grüße vom marabu

padavan 26. Okt 2005 11:56

Re: Listview von doppelten Einträgen befreien.
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo ihr zwei,

also chaosben´s Ansatz war für mich ok, da die doppelten Einträge welche wegfliegen nicht gerettet werden müssen.
Ich habe als Screenshot mal angehängt, wozu das alles überhaupt gut ist (sorry, ist etwas lieblos geworden)

Als Erklärung. Die Listview in der gelöscht werden soll ist nur eine Anzeige von Suchergebnissen.
Da es sich, wie könnte es anders sein, um mp3-Dateien handelt, kann ein Suchbegriff ja im Interpret und im Titel vorkommen.
Also durchlaufe ich beim Suchen beide Spalten. So kann es natürlich passieren, dass ein und der gleiche Titel zweimal gefunden wird -> blödes Beispiel: Suche nach "be" würde BeeGees - Saved by the bell" zweimal aufführen, wobei der Titel eindeutig anhand des Dateinamens beschrieben ist. Ich brauche ihn also nur einmal.

Jetzt hab ich beim erstellen des Screenshot´s noch gemerkt, dass der unterste Titel behalten wird und der oberste rausgekickt.
Das hieße, dass jetzt mehrfach vorkommende BeeGees Titel nicht mehr alphabetisch sortiert sind.
Ändere ich noch...


Natürlich werde ich marabu´s Vorschlag auch ausprobieren, denn das mit den Kommata´s macht mich stuzig.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:49 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