gpt4 book ai didi

delphi - TVirtualStringTree:OnMeasureItem 事件和 OnGetText 事件之间的数据发生变化

转载 作者:行者123 更新时间:2023-12-03 15:01:00 28 4
gpt4 key购买 nike

我有一个数组保存数据将在 TVirtualStringTree 上表示。该数组是线程安全且可锁定的。并由另一个线程增长。

我的问题是,当VST执行OnMeasureItem事件来测量节点的高度时,用于测量的数据在使用OnGetText事件打印数据时可能会发生变化。

我检查了事件的执行顺序,这不利于我的设计。首先,它为所有未初始化的节点触发 OnMeasureItem 事件,然后开始调用 OnGetText 事件。我的意思是,假设我们有 3 个节点,事件将按该顺序触发:

OnMeasureItem for node 1
OnMeasureItem for node 2
OnMeasureItem for node 3
OnGetText for node 1
OnGetText for node 2
OnGetText for node 3

但我需要这样的东西,以便我可以锁定:

OnMeasureItem for node 1
OnGetText for node 1

OnMeasureItem for node 2
OnGetText for node 2

OnMeasureItem for node 3
OnGetText for node 3

保持 OnMeasureItem 和 OnGetText 事件之间获取的数据同步的最佳方法是什么?

我不想在所有 OnMeasureItem() 和 OnGetText() 事件期间锁定我的数组。

谢谢。

添加了 onTimer:

procedure TMainForm.SyncHexLog;
begin
HexLog.BeginUpdate;
Try
if (HexLog.RootNodeCount <> FirpList.ComOperationCountLagged) then
begin
HexLog.RootNodeCount := FirpList.ComOperationCountLagged;

// measure for fast scrolling
HexLog.ReInitNode(HexLog.GetLastNoInit(), True);

if FAutoScroll then
begin
HexLog.ScrollIntoView(HexLog.GetLast, False, False);
end;
end;
Finally
HexLog.EndUpdate;
End;
end;

最佳答案

我会尝试通过从节点状态中删除 vsHeightMeasured 并随后调用 MeasureItemHeight 方法来手动强制项目测量。它将再次触发OnMeasureItem。问题再次出现在这里,因为您不应该多次测量该项目,因为节点的文本发生更改,但仍然必须处理 OnMeasureItem滚动的东西。

因此,正如您在评论中提到的,您可以将自己的 NodeMeasured 标志包含到您的数据结构中,并在节点文本发生更改时(当日志项中的某些数据发生更改时)重置它并在通过带有强制节点高度测量的 OnGetText 事件后设置它。这是一个伪代码:

procedure TForm1.VirtualStringTreeGetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: string);
begin
ThreadList.LockList;
try
// check if the own flag which indicates that the text is new, that
// the data has changed since the last time you were here in OnGetText
// is False and if so, force the node measurement to set current node
// height and set this flag to True to remember we already did this
if not ThreadList.Items[Node.Index].NodeMeasured then
begin
// fake the node measurement, remove the measured flag
Exclude(Node.States, vsHeightMeasured);
// this will trigger the OnMeasureItem again because of removed
// vsHeightMeasured flag from the node's state
VirtualStringTree.MeasureItemHeight(VirtualStringTree.Canvas, Node);
// set the NodeMeasured flag to remember we've measured the item
ThreadList.Items[Node.Index].NodeMeasured := True;
end;
// here set the node's text and unlock your thread safe list
CellText := ThreadList[Node.Index].SomeText;
finally
ThreadList.UnlockList;
end;
end;

在线程中,当数据发生更改时,您必须将此 NodeMeasured 标志设置为 False。

if LogHasChanged then
begin
ThreadList.LockList;
try
ThreadList.Items[X].NodeMeasured := False;
ThreadList.Items[X].SomeText := 'Something new';
finally
ThreadList.UnlockList;
end;
end;

关于delphi - TVirtualStringTree:OnMeasureItem 事件和 OnGetText 事件之间的数据发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10160396/

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