2012-07-28 100 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