Board index » delphi » DBGrid and multiple selection in D1

DBGrid and multiple selection in D1

Quote
Peter Tuente <Peter.Tue...@Materna.DE> wrote:
>Hallo out there,
>i'm trying to support a multiple-line selection in my DBGrid just
>like in Delphi 2 (property: SelectedItems). Does anyone know to
>achieve this?
>Thank you very much in advance
>--
>Peter Tuente     |   Email: Peter.Tue...@Materna.DE | The mission is:
>Dr. Materna GmbH | Telefon: ++49 231 5599 308       | to boldly code
>Vo?kuhle 37      |     Fax: ++49 231 5599 350       | where no one
>D-44141 Dortmund |                                  | has man page 4

At an ealier time in these Delphi forums...
Sylvain Martel <smar...@interlinx.qc.ca>   Wrote:

Each selected rows is a TBookmark. Use DBGrid.SelectedRows as a list
of bookmark

for i := 0 to DBGrid1.SelectedRows.Count -1 do
begin
  Table1.GotoBookMark(DBGrid1.SelectedRows[i]);
  // process the record
end;

Hope that helps!

Rkr

 

Re:DBGrid and multiple selection in D1


Dear Rkr,

D1's DBGrid and D2's DBGrid are quite different.  D1's DBGrid doesn't do
multiple selections and does not have a SelectedRows property.

Dear Peter,

You'll have to write the code yourself: not too hard.

Why not use something like this - create a TList, get the record number of
each row you want selected and add it to the TList:

TL:= TList.create;
...
TL.add(pointer(longint(RecordNumberOfInterest)));
...

this will keep the list of rows.

Now you need a user interface.  Why not intercept the MouseDown and KeyDown
messages (to allow the user to select) and turn DefaultDraw off and use the
OnDrawCell event (to highlight selected cells).

You don't even need to derive a new component! (To answer my question: Why
not: 'cause it will be a bit slow.)

HTH,

--
Paul Motyer
***pa...@linuxserver.pccity.com.au*** currently broken
Croydon, Australia, 3136

rkro...@pacbell.net wrote in article
<5cbmds$...@news4.snfc21.pacbell.net>...

Quote
> Peter Tuente <Peter.Tue...@Materna.DE> wrote:

> >Hallo out there,

> >i'm trying to support a multiple-line selection in my DBGrid just
> >like in Delphi 2 (property: SelectedItems). Does anyone know to
> >achieve this?

> >Thank you very much in advance

> >--
> >Peter Tuente     |   Email: Peter.Tue...@Materna.DE | The mission is:
> >Dr. Materna GmbH | Telefon: ++49 231 5599 308       | to boldly code
> >Vo?kuhle 37      |     Fax: ++49 231 5599 350       | where no one
> >D-44141 Dortmund |                                  | has man page 4

> At an ealier time in these Delphi forums...
> Sylvain Martel <smar...@interlinx.qc.ca>   Wrote:

> Each selected rows is a TBookmark. Use DBGrid.SelectedRows as a list
> of bookmark

> for i := 0 to DBGrid1.SelectedRows.Count -1 do
> begin
>   Table1.GotoBookMark(DBGrid1.SelectedRows[i]);
>   // process the record
> end;

> Hope that helps!

> Rkr

Re:DBGrid and multiple selection in D1


Hi!
I kind of followed your footsteps and created this component.
It implements multiselecting in delphi 1.0

The following code is fully freeware - see below
********************************************************************************************************
********************************************************************************************************
unit Dbmgrid;

(* VERSION 1.0 MultiselectDBGrid
   platform Delphi 1.0

   Author:
   Janne Timmerbacka
   janne.timmeba...@mechaul.com

   This component is fully freeware. But I'm very intressed about new
features or ideas
   that you might have (please mail me).

   Overriden dbgrid functios:
     procedure keydown
       -Escape key -> clearselection
       -Space key -> toggle current row

     function HighLightCell
       -is row selected (for painting)

     procedure MouseDown
       -ssctrl in shift (multiselectin rows)
       -mbright -> popupmenu without losing selection

   Multiselect properties:
     property MultiSelect
       -is multiselection on (if on -> adds dgRowSelect and
dgAlwaysShowSelection to options )

     property MultiSelectedCount
       -how many rows are selected

     procedure GoToMultiSelectedItem
       -go to selected item

     procedure ClearMultiselectList
       -clear selection

   EXAMPLE:
   -Place grid on you form and create datasources and stuff...

     var
       bookmark : TBookmark;
       ii : integer;
     begin
       bookmark := table1.getBookmark;
       table1.disablecontrols;
       if DBMultiGrid.MultiSelectedCount > 0 then
       for ii := 0 to DBMultiGrid.MultiSelectedCount-1 do
       begin
         DBMultiGrid.GoToMultiSelectedItem( ii );
         { now the selected row is current row - do what you wanna do:
            listbox1.items.add( Table1.FieldByName( 'COMPANYNAME'
).AsString );
         }
       end;

       table1.gotoBookmark( bookmark );
       table1.FreeBookmark( bookmark );
       table1.enableControls;
     end;
*)
interface

uses
  WinTypes, Classes, Controls, Grids, DBGrids, dbiprocs, dbitypes, db;

type
  TDBMultiGrid = class(TDBGrid)
  private
    FMultiSelectList : TList;
    FMultiSelect : boolean;

    function GetMultiSelectedCount : integer;
    procedure SetMultiSelect( value : boolean );
  protected
    function GetRecordNumber : Longint;
    function ToggleRowAtMultiSelectList : boolean; virtual;
    function FindFromMultiSelectList( const value : Longint ) :
integer;

    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    function HighlightCell(DataCol, DataRow: Integer; const Value:
string;
      AState: TGridDrawState): Boolean; override;

    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer); override;
  public
    constructor create( aOwner : TComponent ); override;
    Destructor Destroy; override;

    procedure GoToMultiSelectedItem( const value : integer ); virtual;
    procedure ClearMultiselectList; virtual;

  published
    property MultiSelect : boolean read FMultiSelect write
SetMultiSelect default false;
    property MultiSelectedCount : integer read GetMultiSelectedCount;
  end;

implementation

function TDBMultiGrid.GetMultiSelectedCount : integer;
begin
  result := FMultiSelectList.count;
end;(* GetSelectedCount *)

procedure TDBMultiGrid.SetMultiSelect( value : boolean );
begin
  if FMultiSelect <> value then
  begin
    FMultiSelect := value;
    Options := Options + [dgRowSelect, dgAlwaysShowSelection];
  end;
end;(* SetMultiSelect *)

procedure TDBMultiGrid.GoToMultiSelectedItem( const value : integer );
begin
  with DataSource.DataSet do
    if ( value < FMultiSelectList.count ) and ( value >= 0 ) then
      MoveBy( longint( FMultiSelectList.items[ value ]) -
GetRecordNumber );
end;(* GoToMultiSelectedItem *)

function TDBMultiGrid.GetRecordNumber : Longint;
var
  CursorProps: CurProps;
  RecordProps: RECProps;
begin
  with DataSource.DataSet do
  begin
    Check(DbiGetCursorProps(Handle, CursorProps));
    UpdateCursorPos;
    Check(DbiGetRecord(Handle, dbiNOLOCK, nil, @RecordProps));
    Result := RecordProps.iSeqNum;
  end;
end;(* GetRecordNumber *)

function TDBMultiGrid.ToggleRowAtMultiSelectList : boolean;
(* if row is already selected -> deselection and otherway around.
   returns new value (selected = true) *)
var
  value : longint;
  oldindex : integer;
begin
  value := GetRecordNumber;
  OldIndex := FindFromMultiSelectList( value );
  if ( OldIndex = -1 ) then
  begin
    FMultiSelectList.add(pointer(longint(value)));
    result := true;
  end else
  begin
    FMultiSelectList.Delete( OldIndex );
    result := false;
  end;
end;(* ToggleRowAtMultiSelectList *)

function TDBMultiGrid.FindFromMultiSelectList( const value : Longint )
: integer;
(* checks if current row is in a group of selectedrows.
   -Returns : item index = when found
   -Returns : -1 = not found. *)
var
  ii : integer;
begin
  if FMultiSelectList.count > 0 then
  for ii := 0 to FMultiSelectList.count-1 do
    if Longint( FMultiSelectList.Items[ ii ]) = value then
    begin
      result := ii;
      exit;
    end;

  result := -1;
end;(* FindFromMultiSelectList *)

procedure TDBMultiGrid.ClearMultiselectList;
begin
  FMultiSelectList.Clear;
  invalidate;
end;(* ClearMultiSelectList *)

procedure TDBMultiGrid.KeyDown(var Key: Word; Shift: TShiftState);
begin
  with DataSource.DataSet do
{    if ssCtrl in Shift then}
      case Key of
        VK_ESCAPE :
          (* clear selected items *)
          ClearMultiSelectList;

        VK_SPACE :
          ToggleRowAtMultiSelectList;
      end;(* case *)

  Inherited KeyDown( Key, Shift );
end;(* KeyDown *)

function TDBMultiGrid.HighlightCell(DataCol, DataRow: Integer; const
Value: string;
      AState: TGridDrawState): Boolean;
begin
  result := inherited HighLightCell( DataCol, DataRow, Value, Astate
);
  if ( not result ) and ( FMultiSelect ) then
    result := ( FindFromMultiSelectList( GetRecordNumber ) <> -1 );
end;(* HighLightCell *)

procedure TDBMultiGrid.MouseDown(Button: TMouseButton; Shift:
TShiftState;
  X, Y: Integer);
var
  StartFromCountZero : boolean;
  BookMark : TBookMark;
begin
  (* save old position *)
  BookMark := DataSource.DataSet.GetBookMark;

  if ( button = mbright ) and ( FMultiSelect ) then
  begin
    (* right button events -> popupmenu (without clearing selection)
*)
  end else
  begin
    inherited MouseDown( Button, Shift, x, y );

    (* multiselect - add to selection *)
    if ( ssctrl in shift ) and ( button = mbLeft ) and ( FMultiSelect
) then
    begin
      (* is the multiselect list empty when starting selecting *)
      StartFromCountZero := ( FMultiSelectList.Count = 0 );
      (* if already selected -> clear selection and keep old row
selected *)
      ToggleRowAtMultiSelectList;
      (* stay at the really selected row *)
      DataSource.DataSet.GotoBookmark( BookMark );
      DataSource.DataSet.FreeBookmark( BookMark );
      (* if only one selected and selecting more -> (select current
row too)*)
      if ( FMultiSelectList.count = 1 ) and ( StartFromCountZero )
then
        ToggleRowAtMultiSelectList;
    end else(* Multiselect, ctrl + button *)
      ClearMultiselectList;
  end;(* mbleft *)
end;(* mousedown *)

constructor TDBMultiGrid.create( aOwner : TComponent );
begin
  inherited Create( aOwner );

  FMultiSelectList := TList.Create;
  FMultiSelect := false;
end;(* Create *)

Destructor TDBMultiGrid.Destroy;
begin
  FMultiSelectList.Free;

  inherited Destroy;
end;(* Destroy *)

end.
**********************************************************************
"Paremmin ja paremmin"
----------------------------------------------------------------------
Janne Timmerbacka               E-mail:  janne.timmerba...@mechaul.com
Aapelinkatu 10 G 59             WWW:     None
FIN-02230 ESPOO                 Tel:     +358-9-8552801
Finland                         Fax:     Same as Tel
                                GSM:     +358-04-5525448
**********************************************************************

Other Threads