【问题标题】:How to update dataset fields' values using the changed data in user defined FMX TGrid coumns如何使用用户定义的 FMX TGrid 库中更改的数据更新数据集字段的值
【发布时间】:2015-09-09 20:01:10
【问题描述】:

我使用以下方式来定义和填充带有 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 类型的列可以添加到网格中。

我问了一个question 并为其打开了一个赏金,寻找一种通过LiveBindings 填充用户定义列的技术,但在赏金到期日之前我没有得到任何答案。这就是为什么我现在正在尝试另一种方式。 我声明了一个集合 DynamicData: TList<TDynamicRecord>; 并从数据集中填充它。这种方法在@Mike-Sutton 的answer 和他的博客中得到了非常清楚的解释。我设法做到了这一点。数据在网格及其新定义的列中正确显示。

但现在我遇到了另一个问题。我需要更新有关用户活动的数据集。我尝试了父网格的OnSetValueOnEditingDone 事件(根据文档,这些事件将用于数据更新),但奇怪的是它没有触发。

什么是适合更新数据集的正确事件或其他方式?

【问题讨论】:

    标签: delphi firemonkey tgrid


    【解决方案1】:

    我认为问题至少部分解决了。

    有必要重新声明几乎所有的类。如果有人给我建议如何降低代码的复杂性,我会很高兴。

    我必须声明这个类以公开 FOnEditingDoneprocedure 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;
    

    最后我在function TDateColumn.CreateCellControl: TStyledControl;中分配了TDateCell(Result).OnChange := DoDateChanged;

    我远非认为这种方式是最佳的,并且将感谢任何 cmet 和如何优化代码的想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多