如何检测 DBGrid 或 ClientDataset 中的用户在运行时删除了单元格中的数据?

How to detect user either in DBGrid or ClientDataset has deleted data in a cell at runtime?

我有一个程序需要 triggered/fired 用户删除单元格中的数据。看起来 ClientDataset.Delete 不适合这种情况。

我的数据结构是:

TADOConnection -> TADOQuery -> TDataSetProvider -> TClientDataSet -> TDataSource -> TDBGRidEh (descendant of TDBGrid)

我是否需要创建一个程序来检测删除,或者是否已经准备好用于此目的的事件或属性?

下面的代码应该检测您的 CDS 的给定字段(在此示例中为 Customer)何时被修改,因此 它的 AsString 属性 是一个空字符串,或者该字段的值已被 设置为 Null,但在任何一种情况下,前提是该字段之前具有非 Null、非空值。

它使用 TFieldDataLink 的自定义后代来进行检测和处理 dsFieldChange 事件。这只会在 Post 方法正在执行且尚未返回时立即触发。

type
  TMyFieldDataLink = class(TFieldDataLink)
    procedure DataEvent(Event: TDataEvent; Info: Integer); override;
  end;

type
  TForm1 = class(TForm)
    ClientDataSet1: TClientDataSet;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    ADOConnection1: TADOConnection;
    ADOQuery1: TADOQuery;
    DataSetProvider1: TDataSetProvider;
    DBNavigator1: TDBNavigator;
    DBEdit1: TDBEdit;
    procedure FormCreate(Sender: TObject);
  private
    FieldDataLink : TFieldDataLink;
  end;
[...]
procedure TForm1.FormCreate(Sender: TObject);
begin
  FieldDataLink := TMyFieldDataLink.Create;
  FieldDataLink.DataSource := DataSource1;
  FieldDataLink.FieldName := 'Company';
end;

{ TMyFieldDataLink }

procedure TMyFieldDataLink.DataEvent(Event: TDataEvent; Info: Integer);
var
  S : String;
  V : Variant;
begin
  inherited;

  if Event = deFieldChange then begin
    V :=  Field.OldValue;
    if not VarIsNull(V) then begin
      S := V;
      if (S <> '') and (Field <> Nil) and (Field.IsNull or (Field.AsString = '')) then begin
        ShowMessage('Field: ' + Field.FieldName + ' emptied');
      end;
    end;
  end;
end;

要使用,剪切并粘贴到新的 VCL 项目中。

顺便说一句,对于这样的问题,最好从数据集的角度而不是像 DBGrid 这样的特定组件开始。