On closequery of the form I have :
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;
Is there a way I can highlight (or color) a changed cell in cxgrid when I trigger my onclosequery event ?
I don't need to know what was changed but just to know which cell was changed so the user can see it so he can easily decide weather to save the changes or not.
It is simple to get the cxGrid to draw a cell (or row) highlighted in some way using the
cxGrid1DBTableView1CustomDrawCell
event. And by having a flag that indicates that the OnCloseQuery event is in progress, you can restrict its action to inside that event.
Update The code I originally posted with this answer could not successfully mark more than one cell in the current grid row as changed. The updated code below can do this however; note the comments in the two procedures.
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;
For this to work, your TDataSet-descendant type must support correctly returning the original contents of the fields on their OldValue property; TClientDataSet, which I've used to write/test this code certainly does this but I've no idea what actual TDataSet type you're using.
Hopefully, it should be apparent that you could use these two procedures to build a list of TFields that have changed values, including the FieldName OldValue, and Value.