2012-07-28 80 views
0

以下代码位将根据TEdit控件中输入的内容筛选TListView控件的项目,并且如果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. 
+0

不听起来像是要一排过滤器显然是包含或排除的行。看起来很喜欢你想在单元格中粘贴一个空白值,如果它不匹配。如果没有任何列匹配,也许不要添加行... – 2012-07-28 14:34:43

+0

或者你也许可以测试每一列,并且如果它们中的任何一列匹配添加该行,他在经过一段时间的思考后说。更好的是,你将行中的数据和过滤器传递给一个布尔函数,并且如果是true,那么将是更自然的方法。 – 2012-07-28 14:37:59

+0

对不起,我不太理解你的回答。你会再试一次吗?感谢您的答复btw。我所要做的就是创建一个像DBgrid一样的过滤器,但不是使用Dataset的网格,而是简单地使用ListView和编辑控件。 – avue 2012-07-28 14:38:35

回答

3

您清除列表视图,然后您添加到其Items没有SubItems - 这就是为什么其他列是空的。

要过滤列表视图的内容,可能更容易使用列表视图在virtual mode中设置计数并在回调中按需提供数据。这里有一个简单的例子:

形式:

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. 
+0

谢谢,经过一段时间的磨合,我能够使用我的数据库中的信息进行工作。 – avue 2012-07-28 17:56:12