Search code examples
delphifreepascallazarusfpc

Updating StringGrid from Thread


Work is done in a number of threads and a TListView is updated from these threads. They each have a reference to their associated TListItem in the ListView, so it doesn't matter if the listview gets sorted later. The right cell will be updated anyway.

But now I'd like to use a stringgrid instead of listview. However, if the user sorts the stringgrid, how will the thread know what cell to update? I find no reference to put in the thread for the callback. I'd like to have a reference and not have to look up the the right cell every time. Is this possible?

EDIT: Here is what I store in the list we have discussed in comments:

TInfoPackList contain objects of type:

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

There are more members but these are the ones that are relevant to show in the grid.


Solution

  • TStringGrid in Delphi does not have sorting capabilities in which case you would have to sort it manually and as such you will be able to keep a list of which cell belongs to which thread. Easy.

    With TMS TAdvStringGrid you can use the OnRawCompare event to do the comparison of each cell to do a manual sort where you will also be able to keep a list of which cell belongs to which thread.

    But in my honest opinion I would rather do the following:

    • Create one string pointer in each thread. The thread will change that string whenever it wants to.
    • Add that string pointer into a global or parent-global TList or TThreadList depending on whether you have thread-safe ways of accessing the TList or not.
    • Depending on when you want to sort I would sort the list either as soon as the thread changes its string in its string pointer or do the sort after many threads' string pointers have changed maybe via a timer or after a certain amount in a ChangeCounter. TList has a Sort function which you will have to read up on how it is done.
    • After each sort I will then manually populate the StringGrid with the strings in the already sorted list.

    Always keep in mind that you must have thread-safe ways of accessing the Lists. Things like CriticalSections. TThreadList has a lock functionality which locks the list access until unlocked.

    You have to do more work here because just like MBo answered here, unlike TListView a StringGrid only stores strings which it displays and not Objects which you can access from a thread. So that makes it difficult for a thread to know where a string is inside a StringGrid unless you search for it but what about duplicates. So the answer lies in storing your data somewhere else like I described above and then only use the StringGrid to be the display of that data.