Страница 1 из 1

Visual C++ MFC - CListCtrl -> обновление отображаемых дан

Добавлено: Пн май 15, 2006 0:00
tAZAR
Тема посвящается решению проблемы обновления CListCtrl (или ListView в .NET, содержащего большие объемы данных (например - отображающему 10 тысяч записей), получаемых из базы данных или откуда либо еще. Я думаю, тема будет интересна как .NET девелоперам, так и тем, кому ближе MFC.
В моей конкретной ситуации трабл такой:
Есть клиент на C++ под MFC, MySql server 3.53. В клиенте записи базы отображаются в CListCtrl (допустим, список сотрудников. внешний вид - список в 1С Бух. или проч.), содержимое берется из CRecordset каждые 30 секунд (используется только для отображения записей, ака Explorer :-).
Проблему перерисовки, скроллинга и сохранения состояния листа я решил, полосу выделения до краев списка (дальше последнего хидера) нарисовал. Теперь нужно быстро и путево обновлять.
Т.К. выкачивать каждые полминуты все записи запросом - не вариант, нужно определять состояние конкретной таблицы на сервере, чтобы вытащить только изменения, а потом - отобразить эти изменения в CListCtrl. Тупой код типа {lstSotr.DeleteAllItems();
//... обновление листа с нуля } не катит явно.
Если у кого есть предложения - плиз хелп. Сам прорабатываю варианты, но пока нет желания писать Листу AI :-). Кажется, есть простой и более правильный выход...[/b]

Добавлено: Чт май 18, 2006 22:04
JokerR
:)

Добавлено: Пт июн 02, 2006 8:13
Borr
С этим никто не может бороться достаточно эфективно.
На мой взгляд здесь вариант один: Пользователь не может работать с 10000 записей - выход создать удобную систему фильтров, чтобы пользователь получал только то что ему нужно (это обычно не более 100 записей). Т.е. сначало фильтр, создающий SQL запрос а потом уже все остальное - кнопочка "отобразить" Обновление по этой же кнопочке.
ПЛЮСЫ от такой схемы менее загружена сетка и сервер.
А сравнить быстро 10000 тыс записей на клиенте и на сервере это никак не выйдет - единственный вариант здесь:
1 на сервере в таблицу добавить поле TimeStamp (время и дата UPDATE).
С клиента в цикле сравнивать ID записей на предмент удаленных\новых (нет на стороне такой записи с ID - удалена, появились записи с ID > MAX ID на клиенте это будут новые записи) записей и то самое время UPDATE (время на клиенте == времени на стороне сервера) не обновлять если (время на клиенте!= времени на стороне сервера) обновлять.

Добавлено: Ср июн 07, 2006 2:46
tAZAR
Borr писал(а):С этим никто не может бороться достаточно эфективно.
1 на сервере в таблицу добавить поле TimeStamp (время и дата UPDATE).
С клиента в цикле сравнивать ID записей на предмент удаленных\новых (нет на стороне такой записи с ID - удалена, появились записи с ID > MAX ID на клиенте это будут новые записи) записей и то самое время UPDATE (время на клиенте == времени на стороне сервера) не обновлять если (время на клиенте!= времени на стороне сервера) обновлять.
Спасибо за совет, в принципе - идея проходит, только делал я примерно так. Все равно, лист при обновлении немного подвисает(меньше секунды, но при скролле чувствуется...).
А проблему я решил - все в шоколаде. Обновляются только видимые в данный момент записи.
В MFC у CListCtrl есть свойство LVS_OWNERDATA. Ставится на этапе создания ресурса. В общем, лист становится, как бы "виртуальным" (термин не я придумал - накопал в MSDN) и сам берет данные о текущем прорисовываемом элементе из спец. функции. Скорость - бешеная, кол-во обрабатываемых записей при скроллинге и обновлении = кол-во видимых в списке.
Так что, если кому интересно поподробнее - могу расписать.

Добавлено: Чт июн 08, 2006 7:26
Borr
Распиши если не трудно.

Добавлено: Сб июл 08, 2006 10:37
tAZAR
Borr писал(а):Распиши если не трудно.

Сейчас Инет только на работе, поэтому исходников с собой нет (разработкой дома занимаюсь), но, в принципе, в этой статье написано все по этой теме. Собственно, благодаря ей я и решил трабл.
http://subscribe.ru/archive/comp.prog.v ... 80030.html

Еще можно почитать http://www.realcoding.net/article/view/2015#31 - достаточно путевая статья про контролы MFC, немного расширяющая описание оных по сравнению с различными книгами по теме, которые мне попадались..

По пути хочу еще задать вопрос:
То же самое, только на C# реализовать, я думаю, возможно. Как?