Search code examples
delphieditingtdbgridin-place-editor

Delphi : Avoid editing a column in TDBgrid


I know that using a column's readonly property, i can avoid editing its field value. But this doesn't stop the inplace editor to show itself. I need a way to make the column not only protected but "untouchable". Is there a way, please ?


Solution

  • If I understand what you want correctly, you can do this quite simply, by creating a custom TDBGrid descendant and overriding its CanEditShow method, as this determines whether the grid's InplaceEditor can be created:

    type
      TMyDBGrid = class(TDBGrid)
      private
        FROColumn: Integer;
      protected
        function CanEditShow : Boolean; override;
      public
        property ROColumn : Integer read FROColumn write FROColumn;
      end;
    
    function TMyDBGrid.CanEditShow: Boolean;
    begin
      Result := Inherited CanEditShow;
      Result := Result and (Col <> ROColumn);
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      MyDBGrid := TMyDBGrid.Create(Self);
      MyDBGrid.ROColumn := 1;
      MyDBGrid.DataSource := DataSource1;
      MyDBGrid.Parent := Self;
    [...]
    

    This minimalist example just defines one grid column by number as being one where the InplaceEditor is not permitted; obviously you could use any mechanism you like to identify the column(s) for which CanEditShow returns False.

    Note that the code above doesn't account for the fact that the column numbering of the grid changes if you turn off the Indicator column (i.e. set Options.dgIndicator to False);

    Obviously, you get more flexibility for customizing which columns are permitted an InplaceEditor by using an assignable event as in

    type
    
      TAllowGridEditEvent = procedure(Sender : TObject; var AllowEdit : Boolean) of object;
    
      TMyDBGrid = class(TDBGrid)
      private
        FOnAllowEdit: TAllowGridEditEvent;
      protected
        function CanEditShow : Boolean; override;
        procedure DoAllowEdit(var AllowEdit : Boolean);
      public
        property OnAllowEdit : TAllowGridEditEvent read FOnAllowEdit write FOnAllowEdit;
      end;
    
    function TMyDBGrid.CanEditShow: Boolean;
    begin
      Result := Inherited CanEditShow;
      if Result then
        DoAllowEdit(Result);
    end;
    
    procedure TMyDBGrid.DoAllowEdit(var AllowEdit: Boolean);
    begin
      if Assigned(FOnAllowEdit) then
        FOnAllowEdit(Self, AllowEdit);
    end;
    
    procedure TForm1.AllowEdit(Sender: TObject; var AllowEdit: Boolean);
    var
      Grid : TMyDBGrid;
    begin
      Grid := Sender as TMyDBGrid;
      AllowEdit := Grid.Col <> 1;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      MyDBGrid := TMyDBGrid.Create(Self);
      MyDBGrid.ROColumn := 1;
      MyDBGrid.DataSource := DataSource1;
      MyDBGrid.Parent := Self;
      MyDBGrid.OnAllowEdit := AllowEdit;
      [...]
    

    If you don't like creating the grid in code, you could put it in a custom package and install it in the IDE or, if your Delphi version is recent enough, implement the CanEditShow in a class helper.