cxgrid 突出显示(或颜色)更改了表单 closequery 上的单元格

cxgrid highlight (or color) changed cell on form closequery

关于我的表格的关闭查询:

if MessageDlg('Close program ?',
          mtConfirmation, [mbYes,mbCancel],0) <> mrYes then CanClose := False
else if DataModule2.mytable.State in [dsEdit,dsInsert] then
               if MessageDlg('Save changes ?', mtConfirmation,
                    [mbYes,mbNo],0) = mrYes then DataModule2.mytable.Post;

有什么方法可以在触发 onclosequery 事件时突出显示(或着色)cxgrid 中已更改的单元格?

我不需要知道更改了什么,只需要知道更改了哪个单元格以便用户可以看到它,这样他就可以轻松决定天气是否保存更改。

使用 cxGrid1DBTableView1CustomDrawCell 事件。通过有一个标志表明 OnCloseQuery 事件正在进行中,您可以将其操作限制在该事件内部。

更新 我最初发布此答案的代码无法成功将当前网格行中的多个单元格标记为已更改。但是,下面更新的代码可以做到这一点;注意两个中的注释 程序。

type
  TForm1 = class(TForm)
    [...]
  public
    QueryingClose : Boolean;
  end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  try
    QueryingClose := True;
    //{cxGrid1.Invalidate{True);  Do NOT call Invalidate, because it causes the
    //  grid's repainting logic to operate in a way which effectively makes it
    //  impossible to mark more that one cell in the current data row as changed
    ShowMessage('Close?');
  finally
    QueryingClose := False;
  end;
end;

procedure TForm1.cxGrid1DBTableView1CustomDrawCell(Sender:
    TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo:
    TcxGridTableDataCellViewInfo; var ADone: Boolean);
var
  Field : TField;
  MarkCell : Boolean;
  S1,
  S2 : String;
  EC : TcxGridTableEditingController;
begin
  if QueryingClose  and
    (TcxGridDBTableView(Sender).DataController.DataSet.State in[dsEdit, dsInsert]) then begin
    Field := TcxGridDBColumn(AViewInfo.Item).DataBinding.Field;
    S1 := VarToStr(Field.OldValue);

    //  When this event is called, the user may be in the middle of editing a cell's contents
    //  So, the purpose of the following lines is to close the inplace editor being used to do
    //  this amd post the chamged value back to the TField associated with the cell
    EC :=  TcxGridDBTableView(Sender).Controller.EditingController;
    if EC.IsEditing then
      EC.HideEdit(True);

    S2 := VarToStr(Field.Value);
    MarkCell := S1 <> S2;
    if MarkCell then
      ACanvas.Brush.Color := clLime;
  end;
end;

为此,您的 TDataSet 后代类型必须支持在其 OldValue 上正确返回字段的原始内容 属性; TClientDataSet,我已经习惯了 write/test 此代码确实可以做到这一点,但我不知道您使用的实际 TDataSet 类型是什么。

希望您可以使用这两个过程 构建已更改值的 TField 列表,包括 FieldName OldValue 和 Value。