2015-02-18 3 views
0

Работа выполняется в нескольких потоках, а TListView обновляется с этих потоков. У каждого из них есть ссылка на связанный с ними TListItem в ListView, поэтому не имеет значения, будет ли сортировка списка отсортирована позже. В любом случае, правая ячейка будет обновлена.Обновление StringGrid из темы

Но теперь я бы хотел использовать stringgrid вместо listview. Однако, если пользователь сортирует stringgrid, как поток знает, какая ячейка обновляется? Я не нахожу ссылки на помеченные в поток для обратного вызова. Я бы хотел иметь ссылку и не искать каждый раз в правильной ячейке. Это возможно?

EDIT: Вот что я храню в списке мы обсуждали в комментариях:

TInfoPackList содержат объекты типа:

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

Есть больше членов, но они являются те, которые имеют отношение к показать в сетке.

+0

Вы используете TStringGrid или сторонний StringGrid, как AdvStringGrid от TMS? –

+0

Флаги поднимаются вашим почтовым сообщением, но я собираюсь предположить, что вы уже знаете, что VCL не является потокобезопасным и что вы должны делать специальные меры предосторожности при доступе к чему-либо из VCL из потоков. –

+4

Это звучит для меня не так. Нити не должны иметь ссылок на объекты gui. Используйте виртуальный элемент управления. Потоки выполняют свою работу. Пусть они обновляют общую структуру данных. Посмотрите на виртуальный контроль. Используйте любую синхронизацию. –

ответ

1

TStringGrid в Delphi не имеет возможностей сортировки, и в этом случае вам придется сортировать его вручную, и таким образом вы сможете сохранить список принадлежащих ему элементов. Легко.

С помощью TMS TAdvStringGrid вы можете использовать событие OnRawCompare, чтобы выполнить сравнение каждой ячейки, чтобы выполнить ручную сортировку, в которой вы также сможете сохранить список, к которому принадлежит ячейка.

Но в моем честное мнение, я предпочел бы сделать следующее:

  • Создайте один указатель на строку в каждом потоке. Поток будет изменять строку всякий раз, когда захочет.
  • Добавьте указатель на строку в глобальный или родительский глобальный TList или TThreadList в зависимости от , есть ли у вас потокобезопасные способы доступа к TList или нет.
  • В зависимости от того, когда вы хотите сортировать, я бы отсортировал список либо, как только поток изменил свою строку в указателе на строку или выполнил сортировку после того, как указатели строк многих потоков изменились, возможно, через таймер или после определенной суммы в ChangeCounter. TList имеет функцию сортировки, которую вам нужно будет прочитать о том, как это делается.
  • После каждого сортировки я буду вручную заполнять StringGrid строками в уже отсортированном списке.

Всегда помните, что у вас должны быть потоковые способы доступа к спискам. Такие вещи, как CriticalSections. У TThreadList есть функция блокировки, которая блокирует доступ к списку до разблокировки.

Вы должны сделать больше работы здесь, так как MBo ответил здесь, в отличие от TListView, StringGrid хранит только строки, которые он отображает, а не объекты, к которым вы можете получить доступ из потока. Так что это затрудняет для потока знать, где строка находится внутри StringGrid, если вы не ищете ее, а как дублировать. Поэтому ответ заключается в том, чтобы хранить ваши данные где-то в другом месте, как описано выше, а затем использовать StringGrid для отображения этих данных.

+0

BlurrySterk - данные уже хранятся в списке потокобезопасности. Итак, как вы сказали, вместо сортировки сетки я могу отсортировать список и повторно заполнить сетку. Хорошо. Что касается потока, он обновляет сетку, вызывая обработчик событий в форме гридов. Этот обработчик назначается методу в потоке и вызывается через синхронизацию. Но верьте этому или нет, после 5 часов попытки, я не могу понять синтаксис, как назначить строку ячейки stringgrid указателю на строку и так изменить значение в строке ... Можете ли вы показать, как? – Rimfire

+0

Какие типы данных хранятся в списке потокобезопасности? Надеюсь, это настоящие указатели на строки. Если вы повторно заполнили сетку после сортировки, вам не нужно будет определять способ привязки строки ячейки stringgrid к указателю строки и, таким образом, изменить значение в строке. Просто перейдите по отсортированному списку и установите каждую корреляционную ячейку в значение текущего элемента в списке в этой точке цикла. Имеет ли это смысл? Прокрутите список, прочитайте строку текущего элемента и установите ячейку сетки. Будет работать цикл for с индексом I как индекс. Я также укажу на индекс строки сетки. –

+0

Другой вопрос .. Сколько предметов/строк вы говорите здесь? –

1

Нити должны иметь дело с некоторым хранилищем данных, а не с визуальным компонентом. Сетка просто показывает содержимое хранилища данных в необходимом порядке. Если вам нужно сохранить порядок сортировки в хранилище, сохраните индексы.

Обратите внимание, что этот подход напоминает DataSet + TDBGrid

Edit:
1. Конечно, потоки могут обновить визуальные элементы управления, но с минимальной информацией и минимальным потоком данных. Они не предназначены для непрерывного взаимодействия с интерфейсом.
2. Визуальные элементы управления не должны использоваться для хранения данных. Рассмотрим шаблон Model-View-Controller, который стимулирует нас отделять механизмы представления внутренних данных и представления пользовательского представления.

+0

Спасибо, но не является ли распространением для обновления визуальных элементов управления из потоков с помощью указателей методов и синхронизации? Как еще проверить в реальном времени, что происходит внутри потока. – Rimfire

+0

Добавлено в тело ответа – MBo