Delphi. DBGridEh. Как получить данные ячейки при наведении на неё курсора мыши? Хочу при наведении на ячейку DBGridEh получать ID записи и что бы в правой части ячейки появлялась кнопка. Кнопка одна для всех записей, представляет из себя TPanel в инвизе с событием OnClick. Я навожу курсор мыши на ячейку, панель перемещается в нужно место, меняет свойство Visible и Enable на true, в её событии нажатия обрабатываю запись с ID в этой же ячейки. (Выбранная запись в DBgridEh не меняется). Нашел такой способ:procedure TFSprav.DBGridEh2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var grCoord: TGridCoord; aGrid: TCrackDBGrid; NewActiveRecord, oldActiveRecord: integer; delta: string; begin aGrid := TCrackDBGrid(Sender); grCoord := aGrid.MouseCoord(X, Y); aGrid.DataSource.DataSet.DisableControls; oldActiveRecord := aGrid.DataLink.ActiveRecord; // запоминаем текущую строку (отображаемую) не номер записи newActiveRecord := grCoord.Y - aGrid.DataLink.ActiveRecord; // получаем положение строки на которой наведена мышка. aGrid.DataLink.MoveBy(newActiveRecord); delta := aGrid.DataLink.DataSet.FieldByName('Name').AsString; if grCoord.X > 0 then begin caption := delta; end; aGrid.DataLink.ActiveRecord := oldActiveRecord; // возвращаем положение к изначальной строке aGrid.DataSource.DataSet.EnableControls; end; Но возникла трудность. На DataSource стоит обработчик события OnDataChange, который передает ID выбранной в гриде записи в параметры другого ADOQuery. По отдельности оба методы работают, а вместе - нет. Программа залипает в тот момент когда происходит MoveBy у DataSet при изменении положения курсора, он вызывает событие OnDataChange, что при перерисовке видимо опять получает положение мыши и вызывает MoveBy и так по кругу, пока курсор мыши не уберу с грида. Как поправить?
Для того чтобы избежать зацикливания при вызове метода MoveBy в событии OnMouseMove, можно добавить проверку на то, что курсор мыши действительно переместился на другую ячейку в методе OnMouseMove. Например, можно добавить переменную, которая будет хранить предыдущие координаты курсора, и проверять её на изменение перед выполнением метода MoveBy:
var PrevX, PrevY: Integer; procedure TFSprav.DBGridEh2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var grCoord: TGridCoord; aGrid: TCrackDBGrid; NewActiveRecord, oldActiveRecord: integer; delta: string; begin aGrid := TCrackDBGrid(Sender); grCoord := aGrid.MouseCoord(X, Y); if (grCoord.X <> PrevX) or (grCoord.Y <> PrevY) then begin PrevX := grCoord.X; PrevY := grCoord.Y; aGrid.DataSource.DataSet.DisableControls; oldActiveRecord := aGrid.DataLink.ActiveRecord; newActiveRecord := grCoord.Y - aGrid.DataLink.ActiveRecord; aGrid.DataLink.MoveBy(newActiveRecord); delta := aGrid.DataLink.DataSet.FieldByName('Name').AsString; if grCoord.X > 0 then begin caption := delta; end; aGrid.DataLink.ActiveRecord := oldActiveRecord; aGrid.DataSource.DataSet.EnableControls; end; end;
Таким образом, метод MoveBy будет вызываться только при фактическом изменении позиции курсора мыши на другую ячейку, что должно помочь избежать зацикливания в вашей программе.
Для того чтобы избежать зацикливания при вызове метода MoveBy в событии OnMouseMove, можно добавить проверку на то, что курсор мыши действительно переместился на другую ячейку в методе OnMouseMove. Например, можно добавить переменную, которая будет хранить предыдущие координаты курсора, и проверять её на изменение перед выполнением метода MoveBy:
varPrevX, PrevY: Integer;
procedure TFSprav.DBGridEh2MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
grCoord: TGridCoord;
aGrid: TCrackDBGrid;
NewActiveRecord, oldActiveRecord: integer;
delta: string;
begin
aGrid := TCrackDBGrid(Sender);
grCoord := aGrid.MouseCoord(X, Y);
if (grCoord.X <> PrevX) or (grCoord.Y <> PrevY) then
begin
PrevX := grCoord.X;
PrevY := grCoord.Y;
aGrid.DataSource.DataSet.DisableControls;
oldActiveRecord := aGrid.DataLink.ActiveRecord;
newActiveRecord := grCoord.Y - aGrid.DataLink.ActiveRecord;
aGrid.DataLink.MoveBy(newActiveRecord);
delta := aGrid.DataLink.DataSet.FieldByName('Name').AsString;
if grCoord.X > 0 then
begin
caption := delta;
end;
aGrid.DataLink.ActiveRecord := oldActiveRecord;
aGrid.DataSource.DataSet.EnableControls;
end;
end;
Таким образом, метод MoveBy будет вызываться только при фактическом изменении позиции курсора мыши на другую ячейку, что должно помочь избежать зацикливания в вашей программе.