当前位置: 动力学知识库 > 问答 > 编程问答 >

delphi - How to avoid TDbgrid scrolling when returning to a previous location

问题描述:

In the code below, we do some operations (not deletions) on some selected rows.

However, sometimes, when finished, the top selected row has scrolled so that it is displayed 1/2 way down the grid. Is there a way to avoid this scrolling? (If my code to traverse the selected row below is improper for some unrelated reason, I welcome corrections.)

 Function TForm.DoSomethingToSelectedRows;

var

KeyAtStart: Integer;

begin

Result := TRUE;

KeyAtStart := DataSet.FieldByName('Key').AsInteger;

DataSet.DisableControls;

DataSet.First;

try

while Result AND (NOT DataSet.EOF) do DataSet

begin

if DBGrid1.SelectedRows.CurrentRowSelected then

Result := ... do something ...

fMPODataTls.GetDS.Next;

end;

finally

DataSet.Locate('Key', KeyAtStart, []); // re-position where we started

DataSet.EnableControls;

end;

end;

网友答案:

Before looping through the dataset, you can keep note of the top row that the grid is displaying and the number of total records that is displayed. With this information, after you relocate the record, you can position the record to the exact row by moving either to the top or to the bottom and then moving back again.

You can carry out the moving by MoveBys. Unfortunately the Row and RowCount properties of TDBGrid is protected, for that you have to use what is widely known as 'protected hack'.

There's code example in this answer, together with checking bookmarks, so that you don't end up on a wrong record.

网友答案:

There is no guarantee that the current record in your grid is exactly positioned at the center of the visible rows, but doing a Locate when it has scrolled out of sight will make it (the new current record) the middle row of the grid, hence the apparent scrolling.
If you want to re-position the grid as it was, you have to memorize which record is at the top row.

网友答案:

If you are using a TClientDataset, you don't have to mess with the user's cursor, you can clone it and do your edits there.

If I have DBGrid1 linked to ClientDataSet1, and I have the cursor on row 5 of the DBGrid (and the ClientDataSet) and within view of the the first row, and delete the first row using a cloned cursor like below, I'd see the first row disappear and my selected row would go up by one row height.

Function TForm.DeleteFirstRow;
var
  myCDS: TClientDataSet;
begin
  myCDS := myCDS.Create(nil);
  try
    myCDS.CloneCursor(ClientDataSet1, False);
    myCDS.First;
    myCDS.Delete;
  finally
    myCDS.Free;
  end;

If I was scrolled all the way down to row 500 or so, out of view of the first row, and executed it again, the selected row would not move at all in the grid.

分享给朋友:
您可能感兴趣的文章:
随机阅读: