Recent

Author Topic: Here is how to achieve shift-click (contiguous) select on TDBGrid  (Read 2141 times)

grandehombre

  • New member
  • *
  • Posts: 38
Code: [Select]
{
Usage:
in the form that needs this functionality, add

var
    previousGridBookmark: TBookmark;

...
...
...


procedure TfrmTest.DBGrid1CellClick(Column: TColumn);
begin
DBGridShiftSelect(DBGrid1, previousGridBookmark);

  // save last selected bookmark
  previousGridBookmark := DBGrid1.DataSource.DataSet.GetBookmark;
end;


// Don't forget to clear the above bookmark when you clear or re-populate the grid
//
// Example code
//if assigned(previousGridBookmark) then begin
//        DBGrid1.DataSource.DataSet.FreeBookmark(previousGridBookmark);
//        previousGridBookmark := nil;
//    end;


}

Add this code to a unit of its own (or in the form itself, though  it would be best on its own, so it can be reused!)


// Allow shift-Ckick marking of a contiguous block
procedure DBGridShiftSelect(Sender: TObject; existingBookmarks: TBookmark);
var
curPos: TBookmark;
limiter: integer;
grid: TDBGrid;
dSet: TDataSet;
rFrom, rTo, rTmp: integer;
begin
grid := (Sender as TDBGrid);
dSet := grid.DataSource.DataSet;

// Get the current position (bookmark) and record number (the row we shift-clicked on)
curPos := dSet.GetBookmark;
rTo := dSet.RecNo;

dSet.DisableControls;
try
        // dummy loop that allows multiple exits to a single point
repeat
if not (ssShift in GetKeyShiftState) then begin
        exit;
end;

if (existingBookmarks = nil) then begin
exit;
end;

// go to the last bookmark before we shift-clicked
dSet.GotoBookmark(existingBookmarks);
rFrom := dSet.RecNo;

if rTo = rFrom then begin
exit;
end;

// we want to only mark moving forward, so if need be, swap the bookmarks
if rTo < rFrom then begin
rTmp := rTo;
rTo := rFrom;
rFrom := rTmp;
grid.SelectedRows.CurrentRowSelected := True;
dSet.GotoBookmark(curPos);
end;

// stop after marking 255 rows (just in case recNo is not a reliable method of doing this.
// This is probably no longer an issue but it doesn't hurt to leave it here :-)
limiter := 255;
repeat
// highlight current row
grid.SelectedRows.CurrentRowSelected := True;
dset.Next;

rFrom := dSet.recNo;
limiter := limiter - 1;

// keep going until we reach the shift-clicked row
until (limiter < 0) or (rFrom = rTo);
until true;
finally
dSet.FreeBookmark(curPos);
dSet.EnableControls;
end;
end;


UPDATE: Added note on clearing the bookmark when clearing/repopulating the grid
« Last Edit: August 12, 2013, 02:30:42 am by grandehombre »
Lazarus v1.2RC2  i386-win32-win32/win64,  FPC v2.6.2, svn43696 on Win7-64 and win8.1