for*_*ajt 2 delphi listview delphi-7 tlistview
将项目添加到TListView时如何捕获事件?
OnInsert根据文件,我认为该活动将起到作用.它甚至将实际TListItem对象传递给处理程序:
OnInsert在将新项插入列表视图后立即发生.
编写一个OnInsert事件处理程序,以便在项刚刚添加到列表时进行响应.Item参数是添加到Items属性的TListItem对象
这是我的代码:
procedure TForm1.Button1Click(Sender: TObject);
begin
  with ListView1.Items.Add do
  begin
     Caption := 'foo';
     SubItems.Add('bar');
  end;
end;
procedure TForm1.TListView1Insert(Sender: TObject; Item: TListItem);
begin
   //Item is empty
   ShowMessage(Item.Caption);
end;
但令人惊讶的Item.Caption是,它始终是空的.对我来说似乎胡说八道.
编辑:
Items.AddItem()按照建议切换到另一个奇怪的问题.该OnInsert事件处理程序现在将按预期,但TListView不显示TListItem.Caption.
procedure TForm1.Button1Click(Sender: TObject);
begin
  with ListView1.Items.Add do
  begin
     Caption := 'foo1';
     SubItems.Add('bar1');
  end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
  item: TListItem;
begin
  item := TListItem.Create(ListView1.Items);
  item.Caption := 'foo2';
  item.Subitems.Add('bar2');
  ListView1.Items.AddItem(item);
end; 
procedure TForm1.ListView1Insert(Sender: TObject; Item: TListItem);
begin
  //this now works as expected
  ShowMessage(Item.Caption);
end;
为什么是这样?
将TListView.OnInsert新项添加到ListView时,确实会触发该事件.但是,在调用时会将其Item添加到ListView中TListView.Items.Add(),而不是在Button1Click()退出时添加到ListView中.该OnInsert事件处理函数(响应LVN_INSERTITEM通知),同时Add()仍在运行.因此,当然Item在OnInsert事件处理程序将永远是空的,因为你还没有分配任何值呢.
更新:当a TListItem添加到ListView时,未启用LVIF_TEXT基础的标志LVITEM.要显示TListItem.Caption和TListItem.SubItems文本,TListView旨在依靠ListView_SetItemText()与LPSTR_TEXTCALLBACK标志来代替:
此参数可以是LPSTR_TEXTCALLBACK,以指示父窗口存储文本的回调项.在这种情况下,列表视图控件
LVN_GETDISPINFO在需要文本时向父级发送通知代码.
如果在尚未实际位于ListView中的情况下分配TListItem.Captionor TListItem.SubItems属性TListItem,则该LPSTR_TEXTCALLBACK标志将不会应用于这些字段.  LVN_GETDISPINFO不会查询TListView的第一列中没有文本LPSTR_TEXTCALLBACK(如0列有在OS层特殊的含义),但它确实查询中第二列的文本(即使LPSTR_TEXTCALLBACK不应用到它).这就是为什么你的第二个例子缺少'foo2'UI中的标题文本,而不是'bar2'文本.
实际的'foo2'标题字符串存储在TListItem对象中,这就是您ShowMessage()能够工作的原因.
因此,如果您在将项目添加到ListView之前创建新的TListItem并修改它Caption,则必须ListView_SetItemText()手动调用以启用LPSTR_TEXTCALLBACK标题的标记,例如:
uses
  Commctrl;
procedure TForm1.Button2Click(Sender: TObject);
var
  item: TListItem;
begin
  item := TListItem.Create(ListView1.Items);
  item.Caption := 'foo2';
  item.Subitems.Add('bar2');
  ListView1.Items.AddItem(item);
  ListView_SetItemText(ListView1.Handle, item.Index, 0, LPSTR_TEXTCALLBACK);
end; 
或者,Caption临时重置属性值(属性setter在调用之前检查重复的字符串ListView_SetItemText()):
procedure TForm1.Button2Click(Sender: TObject);
var
  item: TListItem;
begin
  item := TListItem.Create(ListView1.Items);
  item.Caption := 'foo2';
  item.Subitems.Add('bar2');
  ListView1.Items.AddItem(item);
  item.Caption := '';
  item.Caption := 'foo2';
end; 
请注意,无论哪种方式,TListItem.Caption文本都不会出现在UI中,直到OnInsert首先调用该事件,因为它在AddItem()运行时被触发.
我在XE2中重现了这一点.如果问题仍然发生在10.2东京,我建议向 Embarcadero 提交一份错误报告.  AddItem()应该LPSTR_TEXTCALLBACK在插入任何已经分配的字符串字段之后强制执行,或者至少应该强制执行Caption.
| 归档时间: | 
 | 
| 查看次数: | 577 次 | 
| 最近记录: |