El componente TListView carece de una propiedad para impedir ítems duplicados, seguramente porque a su vez, los ítems son una clase que además posee subítems.
Una forma para evitar esta situación, sería, antes de agregar el ítem, recorrer la lista y comparar el texto (Caption) del ítem con los ya existentes, una función con un ciclo for to alcanza y es una manera correcta, pero si la lista tiene 15.000 ítems ¿que pasa?, para empezar, una lista del tipo TListView no debería contener tal cantidad y para terminar, también.
Pero TListView tiene un método (función) que hereda de TCustomListView: FindCaption.
{------------------------------------------------------------------------------}
{ TListItems FindCaption }
{------------------------------------------------------------------------------}
function TListItems.FindCaption(StartIndex: Integer; Value: string;
Partial, Inclusive, Wrap: Boolean; PartStart: Boolean): TListItem;
var
I: Integer;
CaptionFound, AllChecked: Boolean;
begin
result := nil;
if (Count = 0) or (StartIndex >= Count) or (not Inclusive and (count = 1)) then Exit;
CaptionFound := False;
AllChecked := False;
if Inclusive then
I := StartIndex
else begin
I := succ(StartIndex);
if I >= Count then I := 0;
end;
if Wrap then Wrap := (StartIndex <> 0);
repeat
if Partial then begin
if PartStart then
CaptionFound := pos(Value, Item[I].Caption) = 1
else
CaptionFound := pos(Value, Item[I].Caption) <> 0;
end else
CaptionFound := Value = Item[I].Caption;
if not CaptionFound then begin
Inc(I);
if Wrap then begin
if I = Count then
I := 0
else
if I = StartIndex then
AllChecked := True;
end else begin
if I = Count then AllChecked := True;
end;
end;
until CaptionFound or AllChecked;
if CaptionFound then result := Item[I];
end;
Las ventajas son las opciones y que ya está hecha.
¿Cómo utilizarla?
if Assigned(ListView1.FindCaption(0,'eltexto',False,True,False,True)) then Exit;
Este código debe ejecutarse antes de agregar un ítem, si el ítem ya existe, entonces FindCaption devuelve un ítem ("completo"), caso contrario, devuelve nil.
Para probarlo basta con este ejemplo:
unit principal;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
ExtCtrls, ShellCtrls, StdCtrls, Buttons;
type
{ TForm1 }
TForm1 = class(TForm)
BAgregar: TBitBtn;
lPath: TLabel;
Lista: TListView;
Panel1: TPanel;
arbol: TShellTreeView;
Splitter1: TSplitter;
procedure arbolClick(Sender: TObject);
procedure BAgregarClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
lPath.Caption:=arbol.Path;
end;
procedure TForm1.BAgregarClick(Sender: TObject);
var
li:TListItem;
begin
if not Assigned(arbol.Selected) then Exit;
if Assigned(Lista.FindCaption(0,arbol.Path,False,True,False,True)) then Exit;
li:=Lista.Items.Add;
li.Caption:=arbol.Path;
end;
procedure TForm1.arbolClick(Sender: TObject);
begin
if not Assigned(arbol.Selected) then Exit;
lPath.Caption:=arbol.Path;
end;
end.
Este programa agrega los nombres de las carpetas mostradas en un TShellTreeView a un TListView nombrada "lista" cada vez que se presiona el botón agregar, evitando duplicados.
No hay comentarios:
Publicar un comentario