Search code examples
delphidbgrid

DBGrid: how to prevent a row from being selected?


I have a grid of entries the user will click on to multi-select for a process. Some of the entries will be invalid based upon values of the first selected row.

I know about DBGrid.SelectedRows.CurrentRowSelected, but I cannot find a suitable place for checking my conditions to set it to True or False.

Something like this:

var
  bm: TBookmark;
  CachedIdentity: String;
  CanSelect: Boolean;
begin
  with dgbSkypeConversations do
  begin
    if SelectedRows.Count > 0 then
    begin
      DataSource.DataSet.DisableControls;
      bm := DataSource.DataSet.GetBookmark;
      CachedIdentity := DataSource.DataSet.FieldByName('identity').AsString;
      DataSource.DataSet.GotoBookmark(SelectedRows[0]);
      CanSelect := DataSource.DataSet.FieldByName('identity').AsString <> CachedIdentity;
      DataSource.DataSet.GotoBookmark(bm);
      DataSource.DataSet.FreeBookmark(bm);
      SelectedRows.CurrentRowSelected := CanSelect; 
      DataSource.DataSet.EnableControls;
    end;
  end
end;

I have tried the OnMouseDown events in Application.OnMessage and of the DBGrid and the Form, but they do not work, and there is no TBookmarkList.BeforeInsertItem event. What can I do or must I change?


Solution

  • I would not make it so complicated.
    If the comparison always takes place on the first selection.
    The code I use here has hardcoded Value.
    No jump around to bookmarks.

    // first selection----------------------------- 
    if DBGrid1.SelectedRows.Count = 1 then begin
       CachedIdentity := 'Sonnenbrille'; // Sunglasses
     //CachedIdentity := DataSource.DataSet.FieldByName('identity').AsString;
       Exit;
    end;
    

    Do the comparison

    if DBGrid1.SelectedRows.CurrentRowSelected then begin
     //if CachedIdentity <> DataSource.DataSet.FieldByName('identity').AsString
       if Pos(LookingFor,DBGrid1.DataSource.DataSet.FieldByName('haupttxt').AsString)=0
       then  DBGrid1.SelectedRows.CurrentRowSelected := False;
       ShowMessage(IntToStr(DBGrid1.SelectedRows.Count));
    end;
    

    We can see two are selected so
    ShowMessage(IntToStr(DBGrid1.SelectedRows.Count));

    shows 2

    enter image description here

    Now we want to select the line

    SPORTLICH, ELEGANTE GUCCI SONNENBRILLE

    We know a simple Pos() Sonnenbrille to find SONNENBRILLE Pos() will be = 0, so a selection-will not take place.

    enter image description here

    ShowMessage(IntToStr(DBGrid1.SelectedRows.Count));

    shows 2 too

    CODE:

    var
    CachedIdentity : string;
    
    procedure TForm2.canSelectedV1;
    begin
        // first selection----------------------------- 
    if DBGrid1.SelectedRows.Count = 1 then begin
       CachedIdentity := 'Sonnenbrille'; // Sunglasses
     //CachedIdentity := DataSource.DataSet.FieldByName('identity').AsString;
       Exit;
    end;
    if DBGrid1.SelectedRows.CurrentRowSelected then
     begin
     //if CachedIdentity <> DataSource.DataSet.FieldByName('identity').AsString
       if Pos(LookingFor,DBGrid1.DataSource.DataSet.FieldByName('haupttxt').AsString)=0
       then  DBGrid1.SelectedRows.CurrentRowSelected := False;
       ShowMessage(IntToStr(DBGrid1.SelectedRows.Count));
     end;
    end;
    
    procedure TForm2.DBGrid1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
    canSelectedV1;
    end;
    
    procedure TForm2.DBGrid1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
    canSelectedV1;
    end;
    
    end.