对于每个选定的列表项目

Jan*_*tze 0 delphi listview listitem

我尝试为每个选定的列表项目执行操作,但它不起作用.这是我试过的:

var
TLsttem:TListItem;
begin
for TLsttem in form1.listview1.Selected do
begin
...
end;
end;
Run Code Online (Sandbox Code Playgroud)

现在我收到此错误:

[dcc32错误] MSGBox.pas(50):E2431 for-in语句无法对集合类型'TListItem'进行操作,因为'TListItem'不包含'GetEnumerator'的成员,或者它不可访问

我怎样才能解决这个问题?

编辑:我现在尝试了这个脚本:

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

但我只得到1条消息,我该如何解决这个问题呢?

LU *_* RD 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; 
Run Code Online (Sandbox Code Playgroud)

TListView.Selected获取第一个选定项目,同时展开GetNextItem更多选定项目.

在此输入图像描述


如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;
Run Code Online (Sandbox Code Playgroud)
procedure TForm1.Button2Click(Sender: TObject);
var
  Item: TListItem;
begin
  for Item in ListView1.SelectedItems do
  begin
    Memo1.Lines.Add(Item.Caption);
  end;
end;
Run Code Online (Sandbox Code Playgroud)


Ste*_*nke 5

虽然对于这个例子来说,这可能是一种过度杀戮,这是一种扩展TListView类的方法,该类具有可以使用for-in循环枚举的SelectedItem属性.

如果循环内的条件可能比仅检查属性或实际提供过滤器委托更复杂,则这可能非常强大.

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;
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

procedure TForm1.Button1Click(Sender: TObject);
var
  item: TListItem;
begin
  for item in ListView1.SelectedItems do
  begin
    ShowMessage(item.Caption);
  end;
end;
Run Code Online (Sandbox Code Playgroud)