2013-02-18 9 views
0

J'ai cherché un certain temps pour une sorte d'un mécanisme qui permettrait de détecter chaque fois qu'un DataGridViewRow d'un DataGridView changé, une fois que DataGridView ne dispose pas d'un moyen simple de le faire. Et je l'ai fait cette mise en œuvreDataGridView Row mise à jour événement

public partial class MyDatagrid : DataGridView 
{ 
    public event EventHandler<RowChangingArgs> RowUpdating; 
    public MyDatagrid() 
    { 
     InitializeComponent(); 
     this.CellBeginEdit += OnCellBeginEdit; 
    } 

    private DataGridViewRow oldRow; 
    private int currentRow; 
    private void OnCellBeginEdit(object sender, DataGridViewCellCancelEventArgs args) 
    { 
     if(oldRow == null || currentRow != args.RowIndex) 
     { 
      if(currentRow != args.RowIndex && oldRow != null) 
      { 
       var newRow = this.Rows[args.RowIndex]; 
       foreach (var cell in oldRow.Cells) 
       { 
        foreach (var cell1 in newRow.Cells.Cast<object>().Where(cell1 => !cell.Equals(cell1))) 
        { 
         if(RowUpdating!= null) 
          RowUpdating.Invoke(this, new RowChangingArgs { OldRow = oldRow, NewRow = newRow}); 
         oldRow.Dispose(); 
         goto called; 
        } 
       } 
      } 
      called: 
      oldRow = this.Rows[args.RowIndex].Clone() as DataGridViewRow; 
      currentRow = args.RowIndex; 
     } 
    } 

    public class RowChangingArgs : EventArgs 
    { 
     public DataGridViewRow OldRow { get; set; } 
     public DataGridViewRow NewRow { get; set; } 
    } 
} 

Exemple:
utilisateur modifie la ligne 1 et la colonne 1, conserve en éditant n colonnes de même rang. L'utilisateur commence à modifier une autre ligne. Incendie avec le contenu ancien de la ligne 1 et le nouveau contenu de la ligne 1.

Est-ce une bonne façon de procéder, ou ai-je oublié quelque chose?

+0

Quel est le but de votre 'dataGridView' hérité? – spajce

+0

détecter chaque fois qu'un DataGridViewRow d'un DataGridView a été modifié. Lancez un événement lorsque l'utilisateur a terminé de changer de ligne. Ainsi, pendant que l'utilisateur édite la même ligne, il mémorise les modifications de ligne en cours. –

+1

vous pouvez utiliser la liaison de données et mettre en œuvre beginedit(), endedit(), canceledit() (décrit ici http://www.codeproject.com/Articles/16408/Discard-changes-in-business-objects) pour mémoriser la ligne en cours . –

Répondre

1

Une autre option ... Si vos données provient d'un « DataTable » ou « DataView » (par exemple à la suite interrogé à partir d'un back-end), données liées de grille source pourrait être d'un DataView. Si tel est le cas, vous pouvez toujours l'avoir directement à partir des gestionnaires d'événements à la gestion du contrôle de la table via ses événements columnChanging ou columnChanged ... selon ce que vous recherchez (pré/post-valeur modifiée).

Si oui, au niveau de la table, après que les données et interrogé renseigné pour la population de la grille, vous pourriez alors ...

YourDataTable.ColumnChanging += MyColumnChanging; 

ont alors une méthode ...

private void MyColumnChanging(object sender, DataColumnChangeEventArgs e) 
{ 
    // just to enforce column name representation, forcing to lower 
    string colName = e.Column.ColumnName.ToLower(); 

    // e.Row has the row that had the change for you to work with, validate, etc... 

    switch (colName) 
    { 
     case "yourcolumnfieldx": 
     doSomething; 
     break; 

     case "anotherfield": 
     doSomethingElse; 
     break; 
    } 
} 
+0

Dieu vous devriez suggérer l'événement RowChanged ou RowChanging, c'est ce que je cherche. Merci! Mais je veux le faire sur le côté de la grille ... –

+1

@BrunoCosta, oui, je comprends cela, mais la grille est liée à la vue datatable/table. La grille de données envoie donc des modifications à la table/vue sous-jacente. Donc, en substance, vous l'obtenez piégé dans la chaîne. Maintenant, pour les grimaces ... vous ailleurs essayez manuellement de mettre à jour la ligne courante de la table/vue en dehors de la grille. Il se déclenche toujours au gestionnaire que j'ai présenté. – DRapp

+0

Je n'ai pas encore testé ma solution, mais je pense que je m'en tiendrai là. Mais oui, votre solution fonctionnerait. –

1

Pourriez-vous essayer:

public string origData { get; set; } 


    private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) 
    { 
     if (e.ColumnIndex == 1) 
      origData = dataGridView1[e.ColumnIndex, e.RowIndex].EditedFormattedValue.ToString().Trim(); //Get the original data 
    } 

    private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) 
    { 
     if (dataGridView1.IsCurrentCellDirty) 
     { 
      if (e.ColumnIndex == 1) 
      { 
       if (origData != dataGridView1[e.ColumnIndex, e.RowIndex].EditedFormattedValue.ToString().Trim()) //If not equal to original data will trigger 
       { 
        //Do stuff 
       } 
      } 
     } 
    } 
+0

Je ne voudrais pas compromettre commencer l'index d'édition. J'essayais juste de savoir si mon code était si mauvais ... –