2009-07-23 4 views
2

Voici mon problème: J'ai un DataGridView lié à une BindingList d'objets personnalisés. Un thread d'arrière-plan met constamment à jour une valeur de ces objets. Les données s'affichent correctement et tout va bien sauf pour une chose - Si vous essayez d'éditer un champ différent pendant que le champ mis à jour en arrière-plan est mis à jour, il perd la valeur entrée. Voici un exemple de code qui illustre ce comportement: (pour une nouvelle forme, déposez un nouveau DataGridView sur :)DatagridView perd l'édition en cours en arrière-plan Mise à jour en arrière-plan

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Threading; 

namespace WindowsFormsApplication2 
{ 
    public partial class Form1 : Form 
    { 
     private BindingList<foo> flist; 
     private Thread thrd; 
     private BindingSource b; 
     public Form1() 
     { 
      InitializeComponent(); 
      flist = new BindingList<foo> 
        { 
         new foo(){a =1,b = 1, c=1}, 
         new foo(){a =1,b = 1, c=1}, 
         new foo(){a =1,b = 1, c=1}, 
         new foo(){a =1,b = 1, c=1} 
        }; 
      b = new BindingSource(); 
      b.DataSource = flist; 
      dataGridView1.DataSource = b; 
      thrd = new Thread(new ThreadStart(updPRoc)); 
      thrd.Start(); 

     } 

     private void upd() 
     { 
      flist.ToList().ForEach(f=>f.c++); 
     } 

     private void updPRoc() 
     { 
      while (true) 
      { 
       this.BeginInvoke(new MethodInvoker(upd)); 
       Thread.Sleep(1000); 
      } 
     } 
    } 


    public class foo:INotifyPropertyChanged 
    { 
     private int _c; 
     public int a { get; set; } 
     public int b { get; set; } 
     public int c 
     { 
      get {return _c;} 
      set 
      { 
       _c = value; 
       if (PropertyChanged!= null) 
        PropertyChanged(this,new PropertyChangedEventArgs("c")); 
      } 
     } 

     #region INotifyPropertyChanged Members 

     public event PropertyChangedEventHandler PropertyChanged; 

     #endregion 
    } 
} 

Ainsi, vous modifier la colonne a ou b, vous verrez que la mise à jour la colonne c vous fait perdre votre entrée.

Toutes les pensées ont apprécié.

+0

Mise à jour - j'ai mis dans une solution qui semble fonctionner. J'ai supprimé l'appel à PropertyChanged et j'appelle à la place DataridView.InvalidateColumn dans le code de mise à jour en arrière-plan. Pas heureux à ce sujet cependant. – user144133

Répondre

0

J'ai joué un peu avec votre code. Il semble que ce qui se passe est que dès que vous ajoutez une nouvelle ligne, un nouvel objet "foo" est automatiquement ajouté au BindingList via la fonctionnalité d'ajout de ligne de 'DataGridView. Comme il est aussi valide qu'un objet dans la collection, son paramètre 'c' sera incrémenté par la fonction thread que vous avez implémentée et vos changements d'entrée seront perdus, puisque le déclenchement de PropertyChangedEvent provoquera l'actualisation de 'DataGridView'.

Ce que je suggère est d'avoir une vue différente, ou un formulaire, où vous entrez les informations du nouvel objet. Ensuite, à OK, ajoutez le nouvel objet foo à la liste. Cela va à l'encontre de l'objectif d'ajouter les lignes directement à partir du DataGridView, je le sais et de discuter avec moi si vous le souhaitez, mais vous pourriez avoir toute votre validation ailleurs. Souhaitez-vous coder toutes vos validations et correctifs dans le code de l'interface utilisateur? Souhaitez-vous un utilisateur à traiter avec "Vous aviez besoin d'un numéro et pas de texte là-bas!" messages pendant que le reste de DataGridView est en cours de mise à jour? Pourrait être un peu frustrant.

De même, si les données doivent être constamment modifiées, il est inutile de les modifier à partir de la grille. Vous voulez un paradigme d'approche connectée à la source de données où une partie de celle-ci est en constante évolution. Vous voudrez peut-être reconsidérer la façon dont vous affichez ces informations et demander à l'utilisateur de voir les données et de les modifier différemment.

Mes 5 cents de toute façon.

Bonne chance yoni, c'était marrant de voir les chiffres devenir fous et je comprends votre problème.

Leo Bruzzaniti

+0

Peut-être que ma question n'était pas assez claire - le problème ne se pose pas lors de l'ajout d'une nouvelle ligne, mais lorsque vous êtes en train de changer la colonne a ou b d'une ligne existante. En outre, la colonne C n'est pas modifiable (dans mon application). À la lumière de l'absence d'autres réponses, je vais supposer que "ce comportement est par conception", et qu'un événement PropertyChanged entraînera toujours la perte des entrées de données actuelles. Les bonnes nouvelles sont que la solution de contournement décrite dans mon commentaire précédent fonctionne. – user144133

+0

Désolé de ne pas être capable de répondre correctement - Je pense qu'éditer une nouvelle ligne et éditer une nouvelle ligne dans ce contexte est la même chose ... que lorsque vous ajoutez vous êtes immédiatement mis en mode d'édition et souffrez toujours du problème. Merci pour les commentaires! –

0

Avant d'enregistrer la propriété assign currentCell du datagridview à rien pour qu'il perd le focus de la cellule en cours de modification

Questions connexes