Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.151.106] |
|
Сообщ.
#1
,
|
|
|
Доброго времени суток, уважаемые форумчане. Прошу вашего совета в возникшем вопросе.
Исходные данные: DBGrid, ZQuery. В ZQuery содержится запрос, в котором выполняется SELECT из нескольких таблиц (использую JOIN'ы). Таблицу прорисовываю вручную (DBGrid.DefaultDrawing := False), т.к. в ней содержится очень много графики (содержимое ячеек подменяются различными картинками). Задача: при клике на ячейку таблицы изменять значение этой ячейки (например, банальный чекбокс) и перерисовывать картинку, в зависимости от измененного содержимого. Попытка №1. Изменение значения в поле напрямую Пробовал в DBGridCellClick() изменять значение поля напрямую через TField. procedure TFrameTemplatePage.DBGridCellClick(Column: TColumn); var lField : TField; lRect : TRect; begin lField := DBGrid.Fields[FGridCoord.X]; //FGridCoord : TGridCoord - номер активной ячейки DBGrid DBGrid.DataSource.DataSet.Edit; if lField.AsInteger = 0 then lField.Value := 1 else lField.Value := 0; lRect := DBGrid.CellRect(FGridCoord.X, FGridCoord.Y); DBGridDrawDataCell(Self, lRect, lField, [gdSelected, gdFocused]); //Перерисовываю содержимое этой ячейки end; procedure TFrameTemplatePage.DBGridDrawDataCell(Sender: TObject; const Rect: TRect; Field: TField; State: TGridDrawState); var lChecked : integer; lStartPoint : TPoint; begin //Для удобства убрал все лишнее, оставив только необходимый код if Field.FieldName <> FCheckFieldTitle then Exit; lChecked := Field.AsInteger; if lChecked = 1 then ImageIndex := 0 else ImageIndex := 2; lStartPoint := GetCenteredLeftTop(Rect, ImageListCheckBoxes.Width, ImageListCheckBoxes.Height); //самописные функции для отрисовки X := StartPoint.X; Y := StartPoint.Y; ImageListCheckBoxes.Draw(DBGrid.Canvas, X, Y, ImageIndex); end; Все работает ровно до того момента пока не кликну потом на другую какую-нибудь ячейку. Выходит сообщение: Cannot update a complex query with more then one table Похоже из-за того что у меня в запросе не одна таблица, такой вариант не прокатывает. Попытка №2. Изменение значения поле через стороннюю ORM, обновление ZQuery и позиционирование к нужной записи ZQuery.Locate TFrameTemplatePage.DBGridCellClick(Column: TColumn); var lField : TField; FieldValue : integer; PKValue : integer; begin FieldValue := FQueryBrowse.FieldByName(FCheckFieldTitle).AsInteger; PKValue := FQueryBrowse.FieldByName(FPKFieldName).AsInteger; FTableRecord.QueryConstructor.ClearConditions; if FieldValue = 0 then FTableRecord.UpdateRecord(PKValue, FCheckFieldName, 1) else FTableRecord.UpdateRecord(PKValue, FCheckFieldName, 0); RefreshBrowse; end; procedure TFrameTemplatePage.RefreshBrowse; var lStr : string; lCurrentRecordID : integer; begin lCurrentRecordID := GetCurrentRecordId; lStr := FTableBrowse.GetSelectQuery; FQueryBrowse.SQL.Text := lStr; FQueryBrowse.Active := TRUE; FQueryBrowse.Locate(PKFieldName, lCurrentRecordID); end; И этот вариант тоже работает, но происходит обновление всей таблицы, а Locate возвращает курсор DBgrid таким образом, что выбранная строка становится первой сверху. Т.е. позиционирование сбивается и дизориентирует пользователя (заметно, когда в таблице количество записей на 2 экрана и больше). Прошу помочь советом. |
Сообщ.
#2
,
|
|
|
Удалось решить проблемы:
С чекбоксами - за счет того, что убрал из базы соответствующее поле и держу ID'ники выбранных записей в памяти. Все прорисовывается отлично. С другими записями - с помощью использования закладок: procedure TFrameTemplatePage.RefreshBrowse; var lMoveByIndex : integer; lBookMark : TBookmark; begin FQueryBrowse.UpdateCursorPos; lBookMark := FQueryBrowse.GetBookmark; FQueryBrowse.DisableControls; try lMoveByIndex := TMyDataSet(FQueryBrowse).FCurrentRecord; FQueryBrowse.SQL.Text := FTableBrowse.GetSelectQuery; FQueryBrowse.Active := TRUE; FQueryBrowse.MoveBy(lMoveByIndex - 1); if FQueryBrowse.BookmarkValid(lBookMark) then FQueryBrowse.GotoBookmark(lBookMark); finally FQueryBrowse.EnableControls; FQueryBrowse.FreeBookmark(lBookMark); end; end; |