![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Согласованность получения данных [D7, XP]
Alex_C © (2011-03-05 10:30:00)Получаю в отдельном треде данные из инета. Затем мне их надо занести в таблицу к уже имеющимся данным. Проблема заключается в следующем: если пользователь просматривает таблицу (делает скроллинг) и в этот момент приходят данные, то естественно у него весь просмотр сбивается (при вставке данных я использую DisableControl).
Интересна следующая идея: как наилучшим образом согласовать вставку данных, чтоб при просмотре таблицы она не мешала пользователю?
Как вариант отказаться от использования DBTable+DBGrid, а использовать другие компоненты.
Anatoly Podgoretsky (2011-03-05 11:49:00) [1]> Alex_C (05.03.2011 11:12:03) [3]
Пусть пользователь вешается, ему ничего другого не остается. Особенно в
современных сетях, когда базу одновременно изменяют сотни и тысячи
пользователей.
Геннадий Петрович (2011-03-05 11:42:00) [2]> // вместо DisableControls
> // вместо EnableControls
К сожалению, DisableControls и EnableControls не виртуальные методы; и даже во внутренние вызовы никак не втиснуться. То есть, совершенно прозрачно сделать не получается. С другой стороны, нет ничего страшного в использовании Freeze- и UnfreezeControls вместо Disable- и EnableControls.
Геннадий Петрович (2011-03-05 11:32:00) [3]> Да, да вот примерно про это я и имел ввиду.
Для полноты картины:
TTLStorage:
const
hack_deFreezeControls = $F0;
hack_deUnfreezeControls = $F1;
procedure TTLStorage.FreezeControls; // вместо DisableControls
begin
DataEvent(TDataEvent(hack_deFreezeControls), 0);
DisableControls;
end;
procedure TTLStorage.UnfreezeControls; // вместо EnableControls
begin
EnableControls;
DataEvent(TDataEvent(hack_deUnfreezeControls), 0);
end;
TTLGridDataLink:
procedure TTLGridDataLink.DataEvent(AEvent: TDataEvent; AInfo: integer);
begin
inherited DataEvent(AEvent, AInfo);
if (Grid is TTLCustomGrid) then
TTLCustomGrid(Grid).InnerDataEvent(AEvent, AInfo);
end;
TTLCustomGrid:
procedure TTLCustomGrid.InnerDataEvent(AEvent: TDataEvent; AInfo: Integer);
begin
{$WARNINGS OFF}
case AEvent of
TDataEvent(hack_deFreezeControls): FreezeScroll;
TDataEvent(hack_deUnfreezeControls): UnfreezeScroll;
end;
{$WARNINGS ON}
end;
function TTLCustomGrid.CreateDataLink: TGridDataLink;
begin
Result := TTLGridDataLink.Create(Self);
end;
function TTLCustomGrid.GetActive: boolean;
begin
Result := (DataSet <> nil) and DataSet.Active;
end;
Alex_C (2011-03-05 11:31:00) [4]Есть конечно вариант вообще безумный))) - он кстати в одном месте моей программы весь удачно реализован:
вот эти данные, что я получаю из инета мне не только в таблицу нужно вывести, но и в графическом виде. Так вот там то все просто - я в памяти рисую потом через BitBlt вывожу на канвас формы - там все великолепно, мерцания вообще нет.
Как вариант - просто таблицу в памяти рисовать, и так же выводить на форму))) Но это шутка... хотя... )))
Alex_C (2011-03-05 11:27:00) [5]
> Запомнить текущую запись, добавить новые, вернуться на запомненую.
Да я так и пробовал - но мигание, особенно если данные начинают идти достаточно активно, весьма раздражает.
Alex_C (2011-03-05 11:26:00) [6]
> Можно использовать ListView.
Именно его сейчас и изучаю. По году в той программе так и сделано.
Другое дело, что у меня в программе
> данные должны ложиться: с сохранением порядка сортировки
а тут получается уже проблема - или отказваться от этого (в принципе это не такая уж и большая потеря), или смериться с мерцанием.
Inovet (2011-03-05 11:23:00) [7]> [3] Alex_C (05.03.11 11:12)
> данные в таблицу добавляются , как бы это сказать, не мешая
> пользователю...
А в чём мешание пользователю проявляется? И что за база что Table пользуешь?
> [0] Alex_C (05.03.11 10:30)
> занести в таблицу к уже имеющимся данным
Т.е. добавить записи?
Запомнить текущую запись, добавить новые, вернуться на запомненую. Добавлять не в этос Dataset. Вообще как может не мешать, если постоянно меняется содержимое записи же не обязательно в конце будут или как там они сортированы?
clickmaker (2011-03-05 11:18:00) [8]> вариант решения этой проблемы есть
есть. Можно использовать ListView. Зависит еще от того, как эти новые данные должны ложиться: с сохранением порядка сортировки или в конец списка, как в виндовом Проводнике новый файл
Alex_C (2011-03-05 11:16:00) [9]
> Геннадий Петрович
Да, да вот примерно про это я и имел ввиду. Сейчас изучаю код - есть несколько не ясных моментов, но сама идея - то, что надо! Спасибо!
Alex_C (2011-03-05 11:12:00) [10]
> Пользователь сам должен решать когда ему обновить НД.
Сергей, понимаешь, там по условию нельзя так делать. Пользователь должен видеть то, что пришло сразу. Никаких кнопок - так сделано во всех других аналогичных программах.
Тут вот почему еще вопрос возник: в одной из программ аналогичных моей, данные в таблицу добавляются , как бы это сказать, не мешая пользователю... Программа написана на визуал базике. Т.е. там все эти мерцания сведены к минимому. Получается вариант решения этой проблемы есть.
Геннадий Петрович (2011-03-05 11:07:00) [11]
procedure TTLCustomGrid.FreezeScroll;
begin
if (FFreezeCount = 0) then
begin
FFreezeKey := CurrentKey;
FFreezeRow := Row;
end;
FFreezeCount := FFreezeCount + 1;
end;
procedure TTLCustomGrid.UnfreezeScroll;
begin
FFreezeCount := FFreezeCount - 1;
if (FFreezeCount = 0) and Active and (CurrentKey = FFreezeKey) then
ScrollActiveToRow(FFreezeRow);
end;
procedure TTLCustomGrid.ScrollActiveToRow(const ARow: integer);
var
TitleOffset: integer;
Distance: integer;
NewRect: TRect;
RowHeight: integer;
NewRow: integer;
begin
if Active then
begin
NewRow := Row;
TitleOffset:= 0;
if (dgTitles in Options) then
inc(iTitleOffset);
if (ARow NewRow) then
begin
BeginUpdate;
try
Scroll(NewRow - ARow);
if ((NewRow - ARow) < 0) then
DataLink.ActiveRecord := 0
else
DataLink.ActiveRecord := VisibleRowCount - 1;
Distance := DataSet.MoveBy(NewRow - ARow);
NewRow := NewRow - Distance;
DataSet.MoveBy(ARow - DataLink.ActiveRecord - TitleOffset);
RowHeight := DefaultRowHeight;
NewRect:= BoxRect(0, TitleOffset, ColCount - 1, 1000);
ScrollWindowEx(Handle, 0, - RowHeight * Distance, @NewRect, @NewRect, 0, nil, SW_Invalidate);
MoveColRow(Col, NewRow, false, false);
finally
EndUpdate;
end;
end;
end;
end;
(C) НеПомнюКто & C°
Сергей М. (2011-03-05 10:52:00) [12]> как наилучшим образом согласовать вставку данных, чтоб при просмотре таблицы она не мешала пользователю?
Никак. Все равно будет мешать.
Пользователь сам должен решать когда ему обновить НД.
Кнопуля у него должна быть соответствующая. Ну и можно еще индикатор некий предусмотреть, извещающий о необходимости рефреша НД с целью получить актуальную его версию.