2014-03-04 51 views
0

我嘗試爲每個選定的listitem做一個操作,但它不會工作。 這是我的嘗試:爲每個選定的listitem

var 
TLsttem:TListItem; 
begin 
for TLsttem in form1.listview1.Selected do 
begin 
... 
end; 
end; 

現在我得到這個錯誤:

[dcc32 Error] MSGBox.pas(50): E2431 for-in statement cannot operate on collection type 'TListItem' because 'TListItem' does not contain a member for 'GetEnumerator', or it is inaccessible

我怎樣才能解決這個問題?

編輯: 我現在嘗試這個腳本:

TLsttem := form1.ListView1.Selected; 
    while TLsttem <> nil do 
    begin 
    showmessage('Test'); 
    TLsttem := form1.ListView1.GetNextItem(TLsttem, sdAll, [isSelected]); 
    end; 

但我只拿到1個消息,我怎麼能解決這個問題?

+1

你不能遍歷一個單一項目('Selected'屬性返回當前選中TListItem),而不是必須用'Items'屬性它返回一個集合。 – RRUZ

+0

你爲什麼使用'form1'全局變量?我敢打賭,代碼在'TForm1'的方法中運行。 –

回答

9

這個例子是從文檔,GetNextItem

procedure TForm1.Button1Click(Sender: TObject); 
var 
    Item: TListItem; 
begin 
    Item := ListView1.Selected; 
    while Item <> nil do 
    begin 
    ListBox1.Items.Add(Item.Caption); 
    Item := ListView1.GetNextItem(Item, sdAll, [isSelected]); 
    end; 
end; 

TListView.Selected獲取選擇的第一項,而GetNextItem解開更多的選擇項目。

enter image description here


正如由David所指出的,有可能此邏輯包裝成一個枚舉,使得for .. in環可以被使用。 最簡單的事情就是把這個枚舉放入類助手中,就像從@StefanGlienke得到的答案一樣。

type 
    TSelectedListItemsEnumerator = record 
    private 
    FListView: TListView; 
    FItem: TListItem; 
    public 
    constructor Create(aListView: TListView); 
    function GetEnumerator: TSelectedListItemsEnumerator; 
    function MoveNext: Boolean; 
    property Current: TListItem read FItem; 
    end; 

    TListViewHelper = class helper for TListView 
    private 
    function GetSelectedItems: TSelectedListItemsEnumerator; 
    public 
    property SelectedItems: TSelectedListItemsEnumerator 
     read GetSelectedItems; 
    end; 

{ TSelectedListItemsEnumerator } 

constructor TSelectedListItemsEnumerator.Create(aListView: TListView); 
begin 
    FListView := AListView; 
end; 

function TSelectedListItemsEnumerator.GetEnumerator: TSelectedListItemsEnumerator; 
begin 
    FItem := nil; 
    Result := Self; 
end; 

function TSelectedListItemsEnumerator.MoveNext: Boolean; 
begin 
    FItem := FListView.GetNextItem(FItem,sdAll,[isSelected]); 
    Result := (FItem <> nil); 
end; 

{ TListViewHelper } 

function TListViewHelper.GetSelectedItems: TSelectedListItemsEnumerator; 
begin 
    Result := TSelectedListItemsEnumerator.Create(Self); 
end; 

procedure TForm1.Button2Click(Sender: TObject); 
var 
    Item: TListItem; 
begin 
    for Item in ListView1.SelectedItems do 
    begin 
    Memo1.Lines.Add(Item.Caption); 
    end; 
end; 
+2

+1。尼斯。不知道GetNextItem。 –

+0

+1。我也是新來的。這是在VCL中實現的,還是由底層控件提供的服務?可以用枚舉器很好地包裝起來。 –

+0

你能回覆我的編輯嗎? 我使用了你的源碼,但只有在我添加一個項目到listview的部分 –

3

這工作完全正常,我在XE5(VCL):

var 
    Item: TListItem; 
begin 
    for Item in ListView1.Items do 
    begin 
    if Item.Selected then 
    begin 
     // Do something with the item 
    end; 
    end; 
end; 
+0

這隻會在列表視圖 –

+0

@ user2735398中取第一項:不,它不會。 :-)它遍歷每個項目,測試每個項目是否被選中。 –

+0

但是,@LURD的答案更好。 –

5

雖然這個例子可能是矯枉過正這裏是與可枚舉與for-in循環一個SelectedItem屬性擴展了TListView類的方法。

如果循環內的條件可能比檢查屬性或實際提供過濾代理更復雜,這可能非常強大。

type 
    TSelectedListItemsEnumerator = class(TListItemsEnumerator) 
    public 
    function MoveNext: Boolean; 
    end; 

    TSelectedListItemsEnumerable = record 
    private 
    FListItems: TListItems; 
    public 
    constructor Create(AListItems: TListItems); 
    function GetEnumerator: TSelectedListItemsEnumerator; 
    end; 

    TListViewHelper = class helper for TListView 
    private 
    function GetSelectedItems: TSelectedListItemsEnumerable; 
    public 
    property SelectedItems: TSelectedListItemsEnumerable 
     read GetSelectedItems; 
    end; 

{ TSelectedListItemsEnumerator } 

function TSelectedListItemsEnumerator.MoveNext: Boolean; 
begin 
    repeat 
    Result := inherited; 
    until not Result or Current.Selected; 
end; 

{ TSelectedListItemsEnumerable } 

constructor TSelectedListItemsEnumerable.Create(AListItems: TListItems); 
begin 
    FListItems := AListItems; 
end; 

function TSelectedListItemsEnumerable.GetEnumerator: TSelectedListItemsEnumerator; 
begin 
    Result := TSelectedListItemsEnumerator.Create(fListItems); 
end; 

{ TListViewHelper } 

function TListViewHelper.GetSelectedItems: TSelectedListItemsEnumerable; 
begin 
    Result := TSelectedListItemsEnumerable.Create(Items); 
end; 

然後,您可以使用它像這樣:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    item: TListItem; 
begin 
    for item in ListView1.SelectedItems do 
    begin 
    ShowMessage(item.Caption); 
    end; 
end; 
相關問題