DBGrid中单击选择多个行

DBGrid中单击选择多个行

本文介绍了在Shift + DBGrid中单击选择多个行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要编写代码以在Shift + MouseClick上选择多个行,以便能够填写这些值。有什么办法可以做到吗?我的DBGrid选项如下:

I need to write the code to select multiple rows on Shift+MouseClick, so that I am able to fill down the values. Is there any way I can do it? My DBGrid options are as follows:

 dbGrid1.Options = [dgEditing, dgAlwaysShowEditor, dgTitles, dgColLines, dgRowLines, dgTabs, dgConfirmDelete, dgCancelOnExit, dgMultiSelect]


推荐答案

我原本以为是个问题这可能是因为Shift + Click是由网格本身处理的,因此,在Grid的OnMouseUp触发时,网格已经将数据集光标移动到了Shift单击的行。因此,将网格选择从Shift-Click之前的位置扩展起来并不是一件容易的事,因为您将缺少ds光标先前所在位置的信息。

I originally thought that a problem you would be likely to have with this is that Shift + Click is handled by the grid itself, so the time the Grid's OnMouseUp fires, the grid has already moved the dataset cursor to the row that was shift-clicked. So extending the grid selection from where it was before the shift-click would not be straightforward, because you would lack the information of where the ds cursor previously was.

但是,事实证明,这样做非常简单。我在下面的代码中添加了一些注释,以解释其工作原理。

However, it turns out to be quite straightforward to do. I've added some comments to the code below to explain how it works.

为简单起见,我使用带有整数ID字段的ClientDataSet实现了它。使用ID字段的要点是,代码在数据集滚动时以某种移交的方式使用ID的当前值和先前值来完成其工作。由于需要不断分配和取消分配书签,因此使用书签进行类似操作会比较麻烦,因此我将其作为读者的练习。

For simplicity, I've implemented it using a ClientDataSet with an integer ID field. The point of using an ID field is that the code uses current and prior values of the ID, in a sort of hand-over-hand way as the dataset scrolls, to do its stuff. Doing similar using bookmarks would be messier because of the need to continually allocate and deallocate them, so I leave that as an exercise for the reader.

代码:

//  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;

这篇关于在Shift + DBGrid中单击选择多个行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 10:13