3

How can I limit the maximum text length of the inplace editor in TDBGrid? (Delphi Berlin)

The Data Type is Float.

kobik
  • 21,001
  • 4
  • 61
  • 121

1 Answers1

7

The inplace editor in a TDBGrid will update its content by calling

procedure TInplaceEdit.UpdateContents;
begin
  Text := '';
  EditMask := Grid.GetEditMask(Grid.Col, Grid.Row);
  Text := Grid.GetEditText(Grid.Col, Grid.Row);
  MaxLength := Grid.GetEditLimit;
end;

Where GetEditMask is implemented the following way:

function TCustomDBGrid.GetEditMask(ACol, ARow: Longint): string;
begin
  Result := '';
  if FDatalink.Active then
  with Columns[RawToDataColumn(ACol)] do
    if Assigned(Field) then
      Result := Field.EditMask;
end;

and GetEditLimit like this:

function TCustomDBGrid.GetEditLimit: Integer;
begin
  Result := 0;
  if Assigned(SelectedField) and (SelectedField.DataType in [ftString, ftWideString]) then
    Result := SelectedField.Size;
end;

There you have multiple ways to get to the desired behavior I think.

  • Use TField EditMask property for the Field you want to restrict. This will be returned by Grid.GetEditMask call. No need to inherit from TDBGrid and override anything. Behavior can be controlled on a by-field-basis.

  • Create your own TDBGrid descendant where you override GetEditLimit to return a MaxLength for the inplace editor depending on SelectedField

Code for approach 1 could look like this:

// Opening of dataset
...
DataSet.FieldByName('FloatField').EditMask := '00.00';

This will mask will require two digits before and after the decimal seperator. See TEditMask for more on masks.

For approach 2:

uses
  Data.DB,
  Vcl.DBGrids;

type
  TMyDBGrid = class(TDBGrid)
  protected
    function  GetEditLimit: Integer; override;
  end;

implementation

{ TMyDBGrid }

function TMyDBGrid.GetEditLimit: Integer;
begin
  Result := inherited GetEditLimit;
  if (Result = 0) and Assigned(SelectedField) and (SelectedField.DataType = ftFloat) then
    Result := 5; // Whatever you decide
end;

Like kobik suggests, you can then use this class as interposer class. To do this, add TDBGrid = class(TMyDBGrid); in the unit you want to use that grid. If you declared TMyDBGrid in the same unit you want to use it, make the type reference clear TMyDBGrid = class(Vcl.DBGrids.TDBGrid).

nil
  • 1,320
  • 1
  • 10
  • 21
  • 1
    Nice answer, I will +1 it if the OP or a reader confirms that it works (don't have time to try it myself right now). – MartynA Aug 09 '17 at 10:52
  • 3
    I did not test this (I leave that to the OP), but I don't see any reason why both suggestions should not work. BTW *Create your own TDBGrid...* - You could use an interposer class for this. – kobik Aug 09 '17 at 11:19
  • Very good suggestion, makes using the grid at design time easier, added that. – nil Aug 09 '17 at 11:45