从线程更新 StringGrid
Updating StringGrid from Thread
工作在多个线程中完成,TListView 从这些线程更新。它们每个都在 ListView 中引用了它们关联的 TListItem,因此稍后是否对列表视图进行排序并不重要。无论如何都会更新正确的单元格。
但现在我想使用 stringgrid 而不是 listview。但是,如果用户对 stringgrid 进行排序,线程将如何知道要更新哪个单元格?我发现没有任何参考可以放入回调线程。我想要一个参考,而不必每次都查找正确的单元格。这可能吗?
编辑:这是我在评论中讨论过的列表中存储的内容:
TInfoPackList 包含以下类型的对象:
TInfoPack = class
ID: Integer;
Name: string;
Location: string;
Thread: TMyThread;
end;
还有更多成员,但这些是与在网格中显示相关的成员。
线程必须处理一些数据存储,而不是可视化组件。
网格只是按需要的顺序显示数据存储的内容。如果您需要在存储中保持排序顺序,请维护索引。
请注意,此方法类似于 DataSet+TDBGrid
编辑:
1. 当然,线程可能会更新可视化控件,但信息最少,数据流最少。它们不适用于与界面的持续交互。
2. 视觉控制不应用于数据存储。考虑模型-视图-控制器模式,它促使我们将内部数据表示和用户视图表示的机制分开。
Delphi 中的 TStringGrid 没有排序功能,在这种情况下,您必须手动对其进行排序,因此您将能够保留一个列表,其中列出了哪个单元格属于哪个线程。简单。
使用 TMS TAdvStringGrid,您可以使用 OnRawCompare 事件对每个单元格进行比较以进行手动排序,您还可以保留一个列表,其中列出了哪个单元格属于哪个线程。
但老实说,我宁愿做以下事情:
- 在每个线程中创建一个字符串指针。线程将改变它
字符串,只要它想。
- 将该字符串指针添加到全局或父全局 TList 或 TThreadList 中,具体取决于
您是否有访问 TList 的线程安全方式。
- 根据你想排序的时间我会排序列表
一旦线程在其字符串指针中更改其字符串,或者在许多线程的字符串指针可能通过计时器或在 ChangeCounter 中更改一定数量后进行排序。 TList 有一个排序函数,你必须阅读它是如何完成的。
- 每次排序后,我将使用已排序列表中的字符串手动填充 StringGrid。
永远记住,您必须以线程安全的方式访问列表。像 CriticalSections 这样的东西。 TThreadList 具有锁定列表访问直到解锁的锁定功能。
你必须在这里做更多的工作,因为就像 MBo 在这里回答的那样,与 TListView 不同,StringGrid 只存储它显示的字符串而不是你可以从线程访问的对象。因此,除非您搜索字符串,否则线程很难知道字符串在 StringGrid 中的位置,但重复项呢?所以答案在于将您的数据存储在其他地方,就像我上面描述的那样,然后只使用 StringGrid 作为该数据的显示。
工作在多个线程中完成,TListView 从这些线程更新。它们每个都在 ListView 中引用了它们关联的 TListItem,因此稍后是否对列表视图进行排序并不重要。无论如何都会更新正确的单元格。
但现在我想使用 stringgrid 而不是 listview。但是,如果用户对 stringgrid 进行排序,线程将如何知道要更新哪个单元格?我发现没有任何参考可以放入回调线程。我想要一个参考,而不必每次都查找正确的单元格。这可能吗?
编辑:这是我在评论中讨论过的列表中存储的内容:
TInfoPackList 包含以下类型的对象:
TInfoPack = class
ID: Integer;
Name: string;
Location: string;
Thread: TMyThread;
end;
还有更多成员,但这些是与在网格中显示相关的成员。
线程必须处理一些数据存储,而不是可视化组件。 网格只是按需要的顺序显示数据存储的内容。如果您需要在存储中保持排序顺序,请维护索引。
请注意,此方法类似于 DataSet+TDBGrid
编辑:
1. 当然,线程可能会更新可视化控件,但信息最少,数据流最少。它们不适用于与界面的持续交互。
2. 视觉控制不应用于数据存储。考虑模型-视图-控制器模式,它促使我们将内部数据表示和用户视图表示的机制分开。
Delphi 中的 TStringGrid 没有排序功能,在这种情况下,您必须手动对其进行排序,因此您将能够保留一个列表,其中列出了哪个单元格属于哪个线程。简单。
使用 TMS TAdvStringGrid,您可以使用 OnRawCompare 事件对每个单元格进行比较以进行手动排序,您还可以保留一个列表,其中列出了哪个单元格属于哪个线程。
但老实说,我宁愿做以下事情:
- 在每个线程中创建一个字符串指针。线程将改变它 字符串,只要它想。
- 将该字符串指针添加到全局或父全局 TList 或 TThreadList 中,具体取决于 您是否有访问 TList 的线程安全方式。
- 根据你想排序的时间我会排序列表 一旦线程在其字符串指针中更改其字符串,或者在许多线程的字符串指针可能通过计时器或在 ChangeCounter 中更改一定数量后进行排序。 TList 有一个排序函数,你必须阅读它是如何完成的。
- 每次排序后,我将使用已排序列表中的字符串手动填充 StringGrid。
永远记住,您必须以线程安全的方式访问列表。像 CriticalSections 这样的东西。 TThreadList 具有锁定列表访问直到解锁的锁定功能。
你必须在这里做更多的工作,因为就像 MBo 在这里回答的那样,与 TListView 不同,StringGrid 只存储它显示的字符串而不是你可以从线程访问的对象。因此,除非您搜索字符串,否则线程很难知道字符串在 StringGrid 中的位置,但重复项呢?所以答案在于将您的数据存储在其他地方,就像我上面描述的那样,然后只使用 StringGrid 作为该数据的显示。