我需要编写代码以在Shift + MouseClick上选择多行,以便我能够填充这些值。有什么办法可以吗?我的DBGrid选项如下:
dbGrid1.Options = [dgEditing, dgAlwaysShowEditor, dgTitles, dgColLines, dgRowLines, dgTabs, dgConfirmDelete, dgCancelOnExit, dgMultiSelect]
答案 0 :(得分:3)
我原本以为你可能遇到的问题是Shift + Click是由网格本身处理的,所以Grid的OnMouseUp触发时,网格已经将数据集光标移动到了那一行。按住Shift键点击。因此,将网格选择从移位点击之前的位置扩展起来并不简单,因为您将缺少ds光标之前的位置信息。
但事实证明这很简单。我在下面的代码中添加了一些注释来解释它是如何工作的。
为简单起见,我使用带有整数ID字段的ClientDataSet实现了它。使用ID字段的关键是代码使用ID的当前值和先前值,在数据集滚动时以一种手动方式执行其操作。使用书签做类似的事情会更加混乱,因为需要不断地分配和取消分配它们,所以我将其作为练习留给读者。
代码:
// Form variables
SettingBookmarkRange : Boolean;
CurrentRowID,
PreviousRowID: Integer;
procedure TForm1.CDS1AfterScroll(DataSet: TDataSet);
begin
if SettingBookmarkRange then exit;
PreviousRowID := CurrentRowID;
CurrentRowID := CDS1.FieldByName('ID').AsInteger;
Caption := Format('Current %d, prior %d', [CurrentRowID, PreviousRowID]);
end;
procedure TForm1.SetBookmarkRange;
var
BM,
TempBM : TBookmark;
NewBM : TBookmarkStr;
FoundPrevious : Boolean;
begin
// This code is called after the user does a Shift-Click in the grid
// First we set a flag to temporarily prevent the CurrrentRowID and
// PreviousrowID from being updated during the dataset's OnScroll event
SettingBookmarkRange := True;
BM := CDS1.GetBookmark;
// Set a flag to keep track of whether we've found the row with the PreviousRowID
FoundPrevious := False;
try
CDS1.DisableControls;
// First, search forwards to see if we can find the the row with the PreviousRowID
// In other words, we're first checking that the Shift-Click was on a row *above*
// the previous row
CDS1.Next;
while not FoundPrevious and not CDS1.Eof do begin
if CDS1.FieldByName('ID').AsInteger = PreviousRowID then begin
FoundPrevious := True;
// We found the row with the PreviousRowID, so now get the Grid to add it, and
// all the rows back to where we started, in its SelectedRows list
while not CDS1.Bof and (CDS1.FieldByName('ID').AsInteger <> CurrentRowID) do begin
DBGrid1.SelectedRows.CurrentRowSelected := True;
CDS1.Prior;
end;
end
else
CDS1.Next;
end;
if not FoundPrevious then begin
// If we get here, the Shift-Click must have been in a row further down the
// grid than the previously-current one
while not FoundPrevious and not CDS1.Bof do begin
if CDS1.FieldByName('ID').AsInteger = PreviousRowID then begin
FoundPrevious := True;
// We found the row with the PreviousRowID, so now get the Grid to add it, and
// all the rows back to where we started, in its SelectedRows list
while not CDS1.Eof and (CDS1.FieldByName('ID').AsInteger <> CurrentRowID) do begin
DBGrid1.SelectedRows.CurrentRowSelected := True;
CDS1.Next;
end;
end
else
CDS1.Prior;
end;
end;
finally
CDS1.GotoBookmark(BM);
CDS1.FreeBookmark(BM);
CDS1.EnableControls;
SettingBookmarkRange := False;
end;
end;
procedure TForm1.DBGrid1MouseUp(Sender: TObject; Button: TMouseButton; Shift:
TShiftState; X, Y: Integer);
begin
Caption := IntToStr(CDS1.Fields[0].Value);
if ssShift in Shift then
SetBookMarkRange;
end;
答案 1 :(得分:0)
多选网格的默认选择行为是Ctrl-Click,而不是Shift-Click。使用它并不需要任何特定的鼠标点击处理程序。
要实现Shift-Click,您必须否决/实现网格的鼠标单击处理程序。
答案 2 :(得分:0)
我为TDBGrid class
使用了插入器。它可以使用 Ctrl + Shift 键:
type
TDBGrid = class(Vcl.DBGrids.TDBGrid)
private
procedure SelectRange;
protected
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer); override;
end;
{...}
implementation
{...}
procedure TDBGrid.SelectRange;
var
CurrentBookMark, CursorBookMark, FirstBookMark, LastBookMark: TBookmark;
Dir: integer;
begin
if SelectedRows.Count <= 1 then
exit;
DataSource.DataSet.DisableControls;
try
FirstBookMark := SelectedRows.Items[0];
LastBookMark := SelectedRows.Items[SelectedRows.Count - 1];
SelectedRows.Clear;
CurrentBookMark := DataSource.DataSet.GetBookmark;
Dir := DataSource.DataSet.CompareBookmarks(FirstBookMark, CurrentBookMark);
if Dir = 0 then
Dir := DataSource.DataSet.CompareBookmarks(LastBookMark, CurrentBookMark);
if Dir > 0 then
DataSource.DataSet.GotoBookmark(LastBookMark)
else if Dir < 0 then
DataSource.DataSet.GotoBookmark(FirstBookMark)
else
Exit;
while not DataSource.DataSet.eof do
begin
CursorBookMark := DataSource.DataSet.GetBookmark;
SelectedRows.CurrentRowSelected := true;
if DataSource.DataSet.CompareBookmarks(CurrentBookMark, CursorBookMark) = 0 then
begin
DataSource.DataSet.FreeBookMark(CursorBookMark);
break;
end;
DataSource.DataSet.FreeBookMark(CursorBookMark);
if Dir < 0 then
DataSource.DataSet.Next
else
DataSource.DataSet.Prior;
end;
DataSource.DataSet.FreeBookMark(CurrentBookMark);
finally
DataSource.DataSet.EnableControls;
end;
end;
{ TDBGrid }
procedure TDBGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
inherited;
if Shift = [ssCtrl, ssShift, ssLeft] then
SelectRange;
end;