Deem |
Отправлено: 17.01.2006, 11:08 |
|
Мастер участка
Группа: Участник
Сообщений: 327
|
Очень надо: задать номер первой отображаемой записи, т.е. после полного рефреша запроса (Active = false; Active = true;) выйти на тот же вид сетки (на активную запись курсор перегнать могу, этого мало!), что и до рефреша.
|
|
avc* |
Отправлено: 17.01.2006, 14:03 |
|
Не зарегистрирован
|
Думаю ему нужно следующее — если верхней в сетке была запись с PK = 5 то и после refresh'а она должна быть там же. Можно достигнуть "точной" подгонкой dataset'а, например функциями DataSet->MoveBy (вычисленное смещение); |
|
olegenty |
Отправлено: 17.01.2006, 14:27 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
ну на нужную запись по PK можно и с помощью Locate выйти. тогда я всё-таки не понял, что требуется.
|
|
avc* |
Отправлено: 17.01.2006, 15:35 |
|
Не зарегистрирован
|
QUOTE |
ну на нужную запись по PK можно и с помощью Locate выйти. тогда я всё-таки не понял, что требуется
|
Я имел ввиду следующее — ну стал ты локатом на нужную запись, а оно должна в быть, допустим, в седьмой строке грида. |
|
olegenty |
Отправлено: 17.01.2006, 15:39 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
вот теперь понятно. мне пока этого ни разу не было нужно.
|
|
avc* |
Отправлено: 17.01.2006, 15:42 |
|
Не зарегистрирован
|
Мне тоже.
Но я могу и ошибаться и Deem имел ввиду нечто другое. |
|
Deem |
Отправлено: 17.01.2006, 17:43 |
|
Мастер участка
Группа: Участник
Сообщений: 327
|
Спасибо за такое участие!!!
Правильно понял AVC. Если делать мягкий рефреш, т.е. при помощи апдейтскуель рефрешить текущую строку — все классно. Но может пригодиться только в случае езменения записи, да и то, если фильтры не задевают изменения (рефрешуемая запись может после изменения не пролазить в фильтр). У меня изменение данных идет строго через диалоги, сетка не знает изменений, пока не дашь команду рефрешить. А добавление и удаление записи не отследит даже тогда, только при включении/выключении датасета. Я уж не говорю про ситуацию, когда база по сети работает, и надо на всех клиентах обновить данные по событию сервера.
Короче, в очень многих случаях надо делать выключение/включение датасета. И даже если я выставлю курсор на ту запись, где она стояла до этого, общая картинка сетки может съехать . Хочу сделать рефрешь так, чтобы юзер не заметил.
Для этого надо заблокировать отображение и после активации запроса выставить ту запись в самый верх грида, которая было до этого.
Не смог, как ни старался, выйти на запись, которая видна в самом верху грида.
" Можно достигнуть "точной" подгонкой dataset'а, например функциями DataSet->MoveBy (вычисленное смещение);"
Посмотрю этот вариант, хотя пока не понял, где можно использовать.
|
|
avc* |
Отправлено: 17.01.2006, 18:13 |
|
Не зарегистрирован
|
QUOTE |
Посмотрю этот вариант, хотя пока не понял, где можно использовать.
|
Например при рефреше. Можно попытаться достутачаться до TCustomGrid::Row и на разностях до и после рефреша подсчитать смещение.
|
|
Deem |
Отправлено: 17.01.2006, 18:47 |
|
Мастер участка
Группа: Участник
Сообщений: 327
|
Попробуем.
|
|
Johnick |
Отправлено: 13.02.2006, 11:58 |
|
Не зарегистрирован
|
Уважаемый, Deem. У меня возникла такая же проблема, что и у тебя.
Пишу локальную базу Paradox. Использую компонент TTable и DBGrid. Данные, которые я получаю по последовательному порту необходимо вносить в эту базу. Данные приходят с периодом 1...2 мин. Так вот, когда данные пишутся в базу, то в DBGrid происходит смещение, хотя я и возвращаюсь на нужную запись, которая была до записи пришедших данных. Удалось ли тебе решить эту проблему? |
|
bmv |
Отправлено: 13.02.2006, 18:25 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 7
|
Что-то наподобие я делал с помощью Bookmark, не знаю может поможет.
CODE |
TDataSet *pDS = DBGrid->DataSource->DataSet;
DBGrid->Visible = false;
// Запоминаем положение курсора
TBookmark SavePlace = pDS->GetBookmark();
// Что-то делаем..
// ...
// Восстанавливаем первоначальное положение курсора
pDS->GotoBookmark(SavePlace);
pDS->FreeBookmark(SavePlace);
// Перерисовываем
DBGrid->Visible = true;
DBGrid->Repaint();
| |
|
olegenty |
Отправлено: 14.02.2006, 08:16 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
2 bmv:
1. Это не гарантирует неизменного положения записи в гриде.
2. Это вообще ничего не гарантирует (никто не сказал, что Bookmark будет Valid после Refresh), и лучше пользоваться Locate.
|
|
Johnick |
Отправлено: 14.02.2006, 10:14 |
|
Не зарегистрирован
|
to BMV:
Спасибо за помощь, но к сожалению это не помогло.
to OLEGENTY:
Спасибо. Locate использовал, тоже не помогает.
Какие есть еще мнения? Может есть какой нибудь метод у грида, чтобы нужная (выбранная) мне запись появлялась в нужной строке грида? |
|
olegenty |
Отправлено: 14.02.2006, 11:30 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
и не должно. см. ответ AVC, он похож на правду.
|
|
bmv |
Отправлено: 14.02.2006, 12:13 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 7
|
QUOTE (Johnick @ 14/02/2006, 10:14) | Какие есть еще мнения? Может есть какой нибудь метод у грида, чтобы нужная (выбранная) мне запись появлялась в нужной строке грида? |
Если все, что было тут перечислено не помогает, то уже ничего не поможет. Если только вывести новый класс из DBGrid и самому там что-нибудь сделать
Я вообще этим компоннетом редко пользуюсь как раз из-за его недостаточной "управляемости". |
|
AVC |
Отправлено: 14.02.2006, 16:27 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Проверенный вариант стабильного курсора в TDBGrid
(не проверял на маленьких выборках) (проверил, работает)
CODE |
//---------------------------------------------------------------------------
// Static DBGrid cursor
//---------------------------------------------------------------------------
class tmpTDBGrid : public TDBGrid
{public:
int __fastcall GetRow (void);
int __fastcall GetRowCount (void);
};
int __fastcall tmpTDBGrid::GetRow (void) { return TCustomGrid::Row; }
int __fastcall tmpTDBGrid::GetRowCount (void)
{
return TCustomGrid::RowCount — ((TDBGrid::Options.Contains(dgTitles))? 1 : 0);
}
//- — - — - — - — - — - — - — - — - — - — - — - — - — - — - — - — - — - — - -
void __fastcall TForm1::Button9Click(TObject *Sender)
{
TDBGrid *grd = DBGrid1;
TDataSet *ds = grd->DataSource->DataSet;
if (!ds) return;
if (!ds->Active)
{ ds->Active = true;
return;
}
// Запомнить текущую строку в сетке
tmpTDBGrid *tgrd = (tmpTDBGrid*)grd;
int oldri = tgrd->GetRow();
int oldID = ds->FieldByName("ID")->AsInteger;
ds->DisableControls();
try {
ds->Active = false;
ds->Active = true;
// Восстановить позицию на запись
ds->Locate("ID", oldID, TLocateOptions());
int newri = tgrd->GetRow();
int vrc = tgrd->GetRowCount(); // visible row count
if (oldri > vrc / 2) // строка из нижней половины — крутить назад
{ ds->MoveBy((1-newri) — (oldri — newri));
ds->MoveBy(oldri-1);
}
else // строка из верхней половины — крутить вперед
{ ds->MoveBy(vrc — oldri);
ds->MoveBy(oldri — vrc);
}
} // try DisableControls
__finally { ds->EnableControls(); }
grd->SetFocus();
}
//---------------------------------------------------------------------------
|
Отредактировано AVC — 14/02/2006, 15:28 |
|
Johnick |
Отправлено: 15.02.2006, 16:33 |
|
Не зарегистрирован
|
to AVC:
Спасибо огромное. Все заработало как часы. |
|