从Thread更新StringGrid

时间:2015-02-18 05:50:30

标签: delphi freepascal lazarus fpc

工作在许多线程中完成,TListView从这些线程更新。它们每个都在ListView中引用了它们相关的TListItem,因此如果listview稍后进行排序并不重要。无论如何,正确的单元格将会更新。

但是现在我想使用stringgrid而不是listview。但是,如果用户对stringgrid进行排序,那么线程将如何知道要更新的单元格?我发现没有引用放入回调的线程。我希望有一个参考,而不必每次都查找正确的单元格。这可能吗?

编辑:以下是我在评论中讨论的列表中存储的内容:

TInfoPackList包含类型为

的对象
TInfoPack = class
  ID: Integer;
  Name: string;
  Location: string;
  Thread: TMyThread;
end;

有更多成员,但这些是与网格中显示相关的成员。

2 个答案:

答案 0 :(得分:1)

线程必须处理一些数据存储,而不是可视组件。 网格只按需要的顺序显示数据存储的内容。如果您需要在存储中保持排序顺序,请维护索引。

请注意,此方法类似于DataSet + TDBGrid

编辑:
当然,线程可以更新可视控件,但信息最少,数据流最小。它们不用于与界面的持续交互 2.不应将可视控件用于数据存储。考虑模型 - 视图 - 控制器模式,它刺激我们分离内部数据表示和用户视图表示的机制。

答案 1 :(得分:1)

Delphi中的TStringGrid没有排序功能,在这种情况下你必须手动对它进行排序,因此你将能够保存哪个单元属于哪个线程的列表。容易。

使用TMS TAdvStringGrid,您可以使用OnRawCompare事件对每个单元格进行比较以进行手动排序,您还可以在其中保留哪个单元格属于哪个线程的列表。

但在我的诚实意见中,我宁愿做以下事情:

  • 在每个线程中创建一个字符串指针。线程会改变它 无论什么时候都要串起来。
  • 将该字符串指针添加到全局或父全局TList或TThreadList中,具体取决于 是否有线程安全的方式访问TList。
  • 根据您要排序的时间,我会对列表进行排序 一旦线程在其字符串指针中更改其字符串,或者在多个线程之后进行排序'字符串指针可能通过计时器或在ChangeCounter中的一定量后更改。 TList有一个排序功能,你必须阅读它是如何完成的。
  • 每次排序后,我将手动使用已排序列表中的字符串填充StringGrid。

请记住,您必须具有访问列表的线程安全方式。像CriticalSections这样的东西。 TThreadList具有锁定功能,可锁定列表访问,直到解锁。

你必须在这里做更多的工作,因为就像MBo在这里回答的那样,与TListView不同,StringGrid只存储它显示的字符串,而不存储你可以从线程访问的对象。所以这使得线程很难知道字符串在StringGrid中的位置,除非你搜索它,但重复的是什么。所以答案在于将数据存储在我上面描述的其他地方,然后只使用StringGrid来显示该数据。