2016-06-29 8 views
1

Auf closequery der Form habe ich:cxgrid Highlight (oder Farbe) geändert Zelle auf Formular 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; 

Gibt es eine Möglichkeit I (oder Farbe) eine veränderte Zelle in cxgrid markieren kann, wenn ich meine OnCloseQuery auslösen Veranstaltung ?

Ich muss nicht wissen, was geändert wurde, aber nur um zu wissen, welche Zelle geändert wurde, damit der Benutzer es sehen kann, so kann er leicht Wetter entscheiden, um die Änderungen zu speichern oder nicht.

+0

Ich denke, Sie müssen vielleicht etwas ausführlicher erklären, was Sie erreichen wollen. Was, wenn mehrere Spalten in derselben Zeile geändert wurden? Wenn Sie "geändert" sagen, möchten Sie Änderungen, die bereits im Datensatz gespeichert sind, einbeziehen? Ist Ihre Datenmenge ApplyUpdates() s? – MartynA

+0

Ja, ich möchte jede Zelle in der gesamten Zeile hervorheben, wenn sie geändert wurde. Dies ist vor dem Post-Ereignis, also ist noch nichts gespeichert. Das Raster befindet sich im Modus [dsEdit, dsInsert]. Nein, die Datenbank ruft applyupdates nicht auf. – user763539

+0

Dies ist die Situation, wenn Benutzer die Tabelle ändert, vergisst, die Änderungen zu buchen und versucht, das Formular zu schließen. Bevor er das Formular schließt (und alle geänderten Daten verliert), ist es schön, ihm zu sagen, dass die Änderungen, die er an der Tabelle vorgenommen hat, noch nicht gespeichert sind und zeigen ihm (die Zellen), die geändert wurden. Verstehen ? Ich dachte vielleicht daran, die veränderte Zelle so einzufärben, dass sie gut sichtbar ist, obwohl das Highlight auch in Ordnung ist. – user763539

Antwort

1

Es ist einfach, das cxGrid dazu zu bringen, eine Zelle (oder Zeile) zu zeichnen, die auf irgendeine Weise unter Verwendung des cxGrid1DBTableView1CustomDrawCell Ereignisses markiert ist. Und wenn Sie ein Flag haben, das anzeigt, dass das OnCloseQuery-Ereignis in Bearbeitung ist, können Sie seine Aktion auf dieses Ereignis beschränken.

Aktualisieren Der Code, der ursprünglich mit dieser Antwort gepostet wurde, konnte nicht erfolgreich mehr als eine Zelle in der aktuellen Rasterzeile als geändert markieren. Der aktualisierte Code unten kann dies jedoch tun; Beachten Sie die Kommentare in den beiden Verfahren.

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; 

Damit dies funktioniert, muss Ihr TDataSet-Nachkomme Typ Rückkehr unterstützen korrekt den ursprünglichen Inhalt der Felder auf ihre Eigenschaft OldValue; TClientDataSet, das ich verwendet habe, um diesen Code zu schreiben/zu testen, tut dies sicherlich, aber ich habe keine Ahnung, welchen tatsächlichen TDataSet-Typ Sie verwenden.

Hoffentlich sollte es offensichtlich sein, dass Sie diese beiden Verfahren zu eine Liste von TFields erstellen können, die Werte geändert haben, einschließlich FieldName OldValue und Value.

+0

Dies hebt geänderte Zellen nicht hervor, wenn Sie von der geänderten Zelle in eine andere Zelle wechseln. Es hebt nur die zuletzt besuchte Zelle in der Zeile hervor, egal ob sie geändert wurde oder nicht. – user763539

+0

Entschuldigung, ich habe die Implementierungsdetails Ihnen überlassen. Sie haben gefragt: "Gibt es eine Möglichkeit, eine veränderte Zelle hervorzuheben (oder zu färben)?" - meine Antwort zeigt, wie man eine Zelle während des OnCloseQuery-Ereignisses besonders hervorhebt/einfärbt. Imo, es liegt an Ihnen zu bestimmen, ob eine bestimmte Zelle ein Kandidat für eine spezielle Behandlung von nicht ist. – MartynA

+0

ok, ich habe die Idee ... danke. – user763539