Ограничить максимальную длину текста встроенного редактора в TDBGrid

Как я могу ограничить максимальную длину текста встроенного редактора в TDBGrid? (Дельфи Берлин)

Тип данных — с плавающей запятой.


person Hossein Yarmohamady    schedule 09.08.2017    source источник
comment
Если вы спрашиваете о максимальной длине текста встроенного редактора, то она зависит от размера основного поля.   -  person Victoria    schedule 09.08.2017
comment
Спасибо за ответ, но у меня данные Float и этот метод не работает   -  person Hossein Yarmohamady    schedule 09.08.2017
comment
Тогда почему вы не упомянули Float в своем вопросе?   -  person MartynA    schedule 09.08.2017
comment
Извините моя ошибка   -  person Hossein Yarmohamady    schedule 09.08.2017


Ответы (1)


Внутренний редактор в TDBGrid обновит свое содержимое, вызвав

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

Где GetEditMask реализовано следующим образом:

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;

и GetEditLimit вот так:

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

Думаю, у вас есть несколько способов добиться желаемого поведения.

  • Используйте свойство TField EditMask для поля, которое вы хотите ограничить. . Это будет возвращено вызовом Grid.GetEditMask. Не нужно наследовать от TDBGrid и что-либо переопределять. Поведение можно контролировать на основе полей.

  • Создайте свой собственный потомок TDBGrid, где вы переопределяете GetEditLimit, чтобы вернуть MaxLength для редактора на месте в зависимости от SelectedField

Код для подхода 1 может выглядеть так:

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

Для этой маски потребуются две цифры до и после десятичного разделителя. Подробнее о масках см. TEditMask.

Для подхода 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;

Как предлагает Кобик, вы можете использовать этот класс в качестве класса интерпозера. Для этого добавьте TDBGrid = class(TMyDBGrid); к единице измерения, которую вы хотите использовать в этой сетке. Если вы объявили TMyDBGrid в том же блоке, в котором хотите его использовать, сделайте ссылку на тип ясной TMyDBGrid = class(Vcl.DBGrids.TDBGrid).

person nil    schedule 09.08.2017
comment
Хороший ответ, я поставлю ему +1, если ОП или читатель подтвердят, что он работает (сейчас нет времени попробовать самому). - person MartynA; 09.08.2017
comment
Я не проверял это (оставляю это на усмотрение ОП), но не вижу причин, по которым оба предложения не должны работать. Кстати, Создайте свой собственный TDBGrid.... Для этого вы можете использовать класс интерпозера. - person kobik; 09.08.2017
comment
Очень хорошее предложение, упрощает использование сетки во время разработки. - person nil; 09.08.2017