2014-03-04 17 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; 
相关问题