Как обновить значения полей набора данных, используя измененные данные в определенных пользователем столбцах FMX TGrid

Я использую следующий способ для определения и заполнения столбца ячейками-предками TCalendarEdit (вот часть интерфейса). Дайте мне знать, если мне нужно раскрыть реализацию.

    type 
      TDynamicRecord = record
        Field1, Field2, Field3: string;
        DateSBU: TDate;
        TimeSBU: TTime;
      end;

      TDateCell = class(TCalendarEdit)
      protected
        procedure SetData(const Value: TValue); override;
      public
        constructor Create(AOwner: TComponent); override;
      end;

      TDateColumn = class(TColumn)
      protected
        function CreateCellControl: TStyledControl; override;
      public
        constructor Create(AOwner: TComponent); override;
      end;

Код работает нормально, и в сетку можно добавить столбец типа TDateColumn.

Я задал вопрос и открыл вознаграждение за него в поисках метода заполнения пользовательского столбца с помощью LiveBindings, но у меня есть нет ответов до истечения срока действия вознаграждения. Поэтому сейчас я пробую другой путь. Я объявляю коллекцию DynamicData: TList<TDynamicRecord>; и заполняю ее из набора данных. Этот подход довольно четко объясняется в ответе @Mike-Sutton и в его блоге. Мне удалось это сделать. Данные правильно отображаются в сетке и во вновь определенных столбцах.

Но теперь я застрял с другой проблемой. Мне нужно обновить набор данных о действиях пользователей. Я попробовал события OnSetValue и OnEditingDone родительской сетки (согласно документации, эти события должны использоваться для обновления данных), но, как ни странно, это не срабатывает.

Что будет правильным событием или другим способом, подходящим для обновления набора данных?


person asd-tm    schedule 09.09.2015    source источник


Ответы (1)


Думаю, что вопрос хотя бы частично решен.

Пришлось переобъявить почти все классы. Я был бы рад, если бы кто-нибудь дал мне совет, как уменьшить сложность кода.

Мне пришлось объявить этот класс, чтобы сделать доступными FOnEditingDone и procedure SetValue(...):

type  
  TDynamicCustomGrid = class(TGrid)
  private
    FOnEditingDone: TOnEditingDone;
  protected
    procedure SetValue(Col, Row: Integer; const Value: TValue);override;
  end;
implementation
  procedure TDynamicCustomGrid.SetValue(Col, Row: Integer; const Value: TValue);
  begin
    inherited;
  end;

Затем я переобъявил

type  
  TDateColumn = class(TColumn)
  protected
    ...
    function Grid: TDynamicCustomGrid; overload;
    procedure DoDateChanged(Sender: TObject);
  public
    ...
  end;
implementation
procedure TDateColumn.DoDateChanged(Sender: TObject);
var
  P: TPointF;
  LGrid: TDynamicCustomGrid;
begin
  LGrid := Grid;
  if not Assigned(LGrid) then
    Exit;
  if FUpdateColumn then
    Exit;
  if FDisableChange then
    Exit;
  P := StringToPoint(TFmxObject(Sender).TagString);
  LGrid.SetValue(Trunc(P.X), Trunc(P.Y), TStyledControl(Sender).Data);
  if Assigned(LGrid.FOnEditingDone) then
    LGrid.FOnEditingDone(Grid, Trunc(P.X), Trunc(P.Y));
end;

function TDateColumn.Grid: TDynamicCustomGrid;
var
  P: TFmxObject;
begin
  Result := nil;
  P := Parent;
  while Assigned(P) do
  begin
    if P is TCustomGrid then
    begin
      Result := TDynamicCustomGrid(P);
      Exit;
    end;
    P := P.Parent;
  end;
end;

И, наконец, я назначил TDateCell(Result).OnChange := DoDateChanged; в function TDateColumn.CreateCellControl: TStyledControl;

Я далек от мысли, что этот путь оптимален и буду признателен за любые комментарии и идеи по оптимизации кода.

person asd-tm    schedule 10.09.2015