2016-06-29 7 views
1

Sur closequery de la forme que j'ai:fort cxgrid (ou couleur) changé cellule sous forme 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; 

Est-il possible que je peux mettre en évidence (ou couleur) une cellule modifiée dans cxgrid lorsque je déclenche mon OnCloseQuery un événement ?

Je n'ai pas besoin de savoir ce qui a été changé, mais de savoir quelle cellule a été modifiée afin que l'utilisateur puisse la voir afin qu'il puisse facilement décider de la météo pour enregistrer les modifications ou non.

+0

Je pense que vous devrez peut-être expliquer un peu plus complètement ce que vous essayez d'accomplir. Que faire si plusieurs colonnes de la même rangée ont été changées? Quand vous dites "changé", voulez-vous dire inclure les changements déjà enregistrés dans l'ensemble de données? Est-ce que votre dataset fait ApplyUpdates() s? – MartynA

+0

Oui, je voudrais mettre en surbrillance chaque cellule de la rangée entière si elle a été changée. Ceci est avant l'événement post donc rien n'est encore enregistré. La grille est en mode [dsEdit, dsInsert]. Non, la base de données dos n'appelle pas applyupdates. – user763539

+0

C'est la situation où l'utilisateur modifie la table, oublie de publier les modifications et essaie de fermer le formulaire. Donc, avant de fermer le formulaire (et de perdre toutes les données modifiées), il est bon de lui dire que les modifications qu'il a apportées à la table ne sont pas encore sauvegardées et lui indiquent (les cellules) qui ont été changées. Comprendre? Je pensais peut-être à colorier la cellule changée afin qu'elle soit facilement visible bien que le point culminant soit ok aussi. – user763539

Répondre

1

Il est simple d'obtenir que le cxGrid dessine une cellule (ou une ligne) mise en surbrillance d'une certaine manière en utilisant l'événement cxGrid1DBTableView1CustomDrawCell. Et en ayant un drapeau qui indique que l'événement OnCloseQuery est en cours, vous pouvez restreindre son action à l'intérieur de cet événement.

Mise à jour Le code que j'ai posté à l'origine avec cette réponse n'a pas pu marquer plus d'une cellule dans la ligne de grille actuelle telle que modifiée. Le code mis à jour ci-dessous peut le faire cependant; Notez les commentaires dans les deux procédures .

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; 

Pour que cela fonctionne, votre type TDataSet-descendant doit prendre en charge correctement retourner le contenu original des champs sur leur propriété OldValue; TClientDataSet, que j'ai utilisé pour écrire/tester ce code, le fait certainement, mais je n'ai aucune idée du type de TDataSet que vous utilisez.

Heureusement, il devrait être évident que vous pouvez utiliser ces deux procédures pour créer une liste de TField ayant des valeurs modifiées, y compris FieldName OldValue et Value.

+0

Cela ne met pas en évidence les cellules modifiées si vous passez d'une cellule modifiée à une autre cellule. Il ne fait que mettre en évidence la dernière cellule visitée dans la rangée, peu importe si elle a été modifiée ou non. – user763539

+0

Désolé, je vous laissais les détails de la mise en œuvre à vous. Vous avez demandé "Existe-t-il un moyen de mettre en évidence (ou de colorier) une cellule modifiée" - ma réponse montre comment mettre en surbrillance/colorer une cellule spécialement pendant l'événement "OnCloseQuery". Imo, c'est à vous de déterminer si une cellule donnée est un candidat pour un traitement spécial de non. – MartynA

+0

ok, j'ai l'idée ... merci. – user763539