过滤多列列表视图

时间:2012-07-28 13:58:38

标签: delphi listview filter

以下代码将根据TListView控件中输入的内容过滤TEdit控件的项目,如果ListView包含单个列,则它可以正常工作,如果您有更多然后是1列,然后在应用过滤器时销毁其他列中的项目,所以我希望有人可能知道在过滤ListView时需要添加到下面的代码中以保留这些列。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, strutils, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    Edit1: TEdit;
    procedure Edit1Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  StrList : TStringList;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
   Index : Integer;
begin
     StrList := TStringList.Create;
     for Index := 0 to ListView1.Items.Count -1 do
        StrList.Add(ListView1.Items[Index].Caption);
end;
procedure TForm1.Edit1Change(Sender: TObject);
var
   Index : Integer;
begin
   ListView1.Clear;
   for Index := 0 to StrList.Count - 1 do
     if Pos(Edit1.Text, StrList.Strings[Index]) > 0 then
        ListView1.AddItem(StrList.Strings[Index], nil);
   if Edit1.Text = '' then
     for Index := 0 to StrList.Count - 1 do
       ListView1.AddItem(StrList.Strings[Index], nil);
end;


end.

1 个答案:

答案 0 :(得分:3)

您正在清除列表视图,然后在没有Items的情况下添加到SubItems - 这就是其他列为空的原因。

要过滤listview的内容,可能更容易使用virtual mode中的listview,您可以在其中设置计数并在回调中按需提供数据。这是一个简单的例子:

表格:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 282
  ClientWidth = 418
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  PixelsPerInch = 96
  TextHeight = 13
  object ListView1: TListView
    Left = 8
    Top = 39
    Width = 402
    Height = 235
    Columns = <
      item
        Caption = 'Name'
        Width = 80
      end
      item
        Caption = 'Title'
        Width = 160
      end
      item
        Alignment = taRightJustify
        Caption = 'Age'
        Width = 80
      end>
    OwnerData = True
    SortType = stText
    TabOrder = 0
    ViewStyle = vsReport
    OnData = ListView1Data
  end
  object Edit1: TEdit
    Left = 8
    Top = 12
    Width = 121
    Height = 21
    TabOrder = 1
    OnChange = Edit1Change
  end
end

代码:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, System.Contnrs,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Grids, Vcl.ComCtrls;

type
  TDataItem = class
  private
    FAge: Integer;
    FFirstName: string;
    FLastName: string;
  public
    property Age: Integer read FAge;
    property FirstName: string read FFirstName;
    property LastName: string read FLastName;
  end;

  TForm1 = class(TForm)
    ListView1: TListView;
    Edit1: TEdit;
    procedure ListView1Data(Sender: TObject; Item: TListItem);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
  private
    FActiveItems: TList;
    FItems: TObjectList;
    procedure AddTestData;
    procedure ApplyFilter(const S: string = '');
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AddTestData;
  procedure AddDataItem(const FirstName, LastName: string; Age: Integer);
  var
    DataItem: TDataItem;
  begin
    DataItem := TDataItem.Create;
    try
      DataItem.FFirstName := FirstName;
      DataItem.FLastName := LastName;
      DataItem.FAge := Age;
      FItems.Add(DataItem);
    except
      DataItem.Free;
      raise;
    end;
  end;
begin
  AddDataItem('John', 'Doe', 26);
  AddDataItem('Jane', 'Warwick', 29);
  AddDataItem('Stephen', 'Marley', 33);
  AddDataItem('Alice', 'Connoly', 48);
  AddDataItem('Adam', 'Spears', 63);
end;

procedure TForm1.ApplyFilter(const S: string);
var
  I: Integer;
begin
  ListView1.Items.BeginUpdate;
  try
    ListView1.Clear;
    FActiveItems.Clear;
    for I := 0 to FItems.Count - 1 do
      if (S = '') or (Pos(UpperCase(S), UpperCase(TDataItem(FItems[I]).FirstName)) <> 0) then
        FActiveItems.Add(FItems[I]);
    ListView1.Items.Count := FActiveItems.Count;
  finally
    ListView1.Items.EndUpdate;
  end;
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
  ApplyFilter((Sender as TEdit).Text);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FItems := TObjectList.Create;
  FActiveItems := TList.Create;
  AddTestData;
  ApplyFilter(Edit1.Text);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FActiveItems.Free;
  FItems.Free;
end;

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
var
  DataItem: TDataItem;
begin
  DataItem := FActiveItems[Item.Index];
  Item.Caption := DataItem.FirstName;
  Item.SubItems.Add(DataItem.LastName);
  Item.SubItems.Add(IntToStr(DataItem.Age));
end;

end.