2009-11-05 7 views
1

J'essaye de lier une collection (qui hérite de BindingList) à un DataGridView. Les en-têtes de la grille s'affichent bien et le nombre de lignes que j'attends. Cependant, les cellules sont vides. Quelqu'un d'autre a-t-il eu ce problème? Si c'est le cas, comment l'as-tu résolu? J'ai parlé à quelqu'un d'autre qui a eu le même problème mais ils ne peuvent pas se rappeler comment ils l'ont résolu. J'ai essayé de créer une version simple qui montre le problème mais qui n'a pas eu de chance. Je suis désolé, je n'ai inclus aucun code.Les lignes DataGridView s'affichent mais aucune donnée

EDIT # 1:

Je ne pense pas que ce code vous aidera, mais juste au cas où. J'ai simplifié les choses pour éviter de devoir esquisser les 47 couches de notre code. Mais comme je l'ai dit, je ne peux pas recréer le problème avec un exemple très simple comme celui-ci. Je ne veux pas vraiment d'analyse de code - juste des mots de sagesse de ceux qui ont rencontré ce problème. Sûrement je ne suis pas le seul.

public interface ISearchResultCollection : IList<ISearchResult> 
{ 
... 
} 

public class SearchResultCollection : BindingList<ISearchResult>, ISearchResultCollection 
{ 
... 
} 

public interface ISearchResult 
{ 
    ILineNum LineNumber {get; set;} 
    string Text {get; set;} 
} 

public class SearchResult 
{ 
... 
} 

ISearchResultCollection results = objectToSearch.Find("searchstring"); 
dataGridView1.DataSource = results; 

EDIT # 2:

Je pense que j'ai une avance. Toutes les propriétés publiques de mon interface représentant un élément (ISearchResult) sont également des types d'interface. J'ai ajouté une propriété de chaîne et ses données apparaissent magiquement. Ainsi, dans l'exemple ci-dessus, les données de la colonne Text apparaîtraient. Mais, les données de la colonne LineNumber ne seraient pas car il s'agit d'un type d'interface (ILineNum). Je pensais que ToString() serait appelé pour remplir la grille sur ceux-ci. Des idées maintenant?

+0

Pouvez-vous donner d'autres exemples d'objets que vous essayez de lier? Par exemple, à quoi ressemble la "collection qui hérite de BindingList"? Comment liez-vous votre objet à DataGridView? Directement ou via une BindingSource? Êtes-vous sûr que votre objet contient des données? Il est très difficile de répondre sans code à analyser. :) –

+0

J'ai fait quelques modifications pour inclure un shell du code. Je ne suis pas sûr que cela aidera beaucoup. J'ai vérifié qu'il y a des données dans le débogueur. – bsh152s

Répondre

1

Lorsque vous indexez un objet sur un certain contrôle, les interfaces de liaison de données appellent automatiquement "ToString()" sur votre objet afin que vous obteniez une représentation de chaîne décente dans le contrôle auquel vous liez. Dans le cas d'un DataGridView, vous verrez la représentation ToString'd de l'objet sous-jacent dans la cellule appropriée. Toutefois, lorsque vous effectuez une connexion de données à une interface, aucun appel de ToString() n'est effectué. Cela signifie que votre DataGridView affichera une cellule vide mais ceci est assez trompeur car l'objet lié est réellement là comme il se doit - il n'a juste aucune valeur à afficher dans la cellule.

Pour résoudre ce problème, vous devez vous occuper du formatage d'une valeur d'affichage. Dans un DataGridView, cela peut être réalisé en gérant l'événement CellFormatting. Cet événement est déclenché chaque fois qu'une cellule a besoin de formater sa valeur, donc vous devez faire attention à ne pas mettre trop de logique lourde dans ce gestionnaire. Dans votre cas, tout ce que vous avez à faire est d'appeler "ToString()" sur l'objet sous-jacent. Ainsi, vous pouvez gérer l'événement CellFormatting alors utiliser quelque chose comme ceci dans votre gestionnaire:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
{ 
    if (e.Value != null && dataGridView1.Columns[e.ColumnIndex] == theRelevantColumn) 
    { 
     e.Value = e.Value.ToString(); 
    } 
} 

Dans l'extrait ci-dessus, nous vérifions pour une colonne spécifique avant d'effectuer la logique, mais cela est facultatif, votre propre scénario peut être différent. Le point principal à noter est que nous obtenons l'objet original passé sur les arguments de l'événement et tout ce que nous devons faire est de remettre la valeur formatée dans les arguments de l'événement. Dans ce cas, la valeur formatée est générée en appelant "ToString()" sur l'objet sous-jacent. Dans votre DataGridView, vous verrez maintenant cette valeur formatée dans la cellule appropriée.

Espérons que ça aide.

0

Vous devez définir AllowUserToAddRows sur false;

Questions connexes