gpt4 book ai didi

listview - TListView:已添加项目?

转载 作者:行者123 更新时间:2023-12-02 16:13:10 25 4
gpt4 key购买 nike

当项目添加到 TListView 时,如何捕获事件?

根据文档,我认为 OnInsert 事件可以完成这项工作。它甚至将实际的 TListItem 对象传递给处理程序:

OnInsert Occurs immediately after a new item is inserted into the list view.

Write an OnInsert event handler to respond when an item has just been added to the list. The Item parameter is the TListItem object that was added to the Items property

这是我的代码:

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;

image

这是为什么?

最佳答案

TListView.OnInsert当新项目添加到 ListView 时,事件确实会被触发。然而,ItemTListView.Items.Add() 时添加到 ListView被调用,而不是在 Button1Click() 时调用退出。 OnInsertLVN_INSERTITEM 时调用事件处理程序(响应 Add() 通知)仍在运行。所以,当然是ItemOnInsert事件处理程序将始终为空,因为您尚未为其分配任何值。

<小时/>

更新:当 TListItem添加到 ListView 后,LVIF_TEXT底层证券标志 LVITEM 未启用。显示TListItem.CaptionTListItem.SubItems文本,TListView设计依赖 ListView_SetItemText() LPSTR_TEXTCALLBACK改为标记:

This parameter can be LPSTR_TEXTCALLBACK to indicate a callback item for which the parent window stores the text. In this case, the list-view control sends the parent an LVN_GETDISPINFO notification code when it needs the text.

如果您分配TListItem.CaptionTListItem.SubItems属性(property)而TListItem实际上还没有在 ListView 中,LPSTR_TEXTCALLBACK标志不会应用于这些字段。 LVN_GETDISPINFO不会查询TListView对于没有 LPSTR_TEXTCALLBACK 的第一列文本(因为第 0 列在操作系统层具有特殊含义),但它确实查询第二列的文本(即使 LPSTR_TEXTCALLBACK 未应用于它)。这就是为什么你的第二个例子缺少 'foo2' UI 中的标题文本,但不是 'bar2'文本。

实际'foo2'标题字符串存储在TListItem中对象,这就是为什么你的 ShowMessage()可以工作。

所以,如果您创建一个新的 TListItem并修改其Caption在将项目添加到 ListView 之前,您必须调用 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直到 OnInsert 之后文本才会出现在 UI 中首先调用事件,因为它是在 AddItem() 时触发的。正在运行。

我在 XE2 中重现了这个。如果问题在10.2东京仍然出现,我建议filing a bug report与内河码头。 AddItem()可能应该强制LPSTR_TEXTCALLBACK插入任何已分配的字符串字段后,或至少 Caption无论如何。

关于listview - TListView:已添加项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45806324/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com