Comment obtenir le nom de mappage approprié à partir d'une source de liaison liée à une liste & Lt; T > ;, ou à un type anonyme, à utiliser sur un DataGridTableStyle?

StackOverflow https://stackoverflow.com/questions/420386

Question

J'essaie de créer un objet DataGridTableStyle afin de pouvoir contrôler la largeur des colonnes d'un DataGrid. J'ai créé un objet BindingSource lié à une liste. En fait, il est lié à une liste de types anonymes créée via Linq de la manière suivante (les noms de variables ont été modifiés pour clarifier ce que je fais):

List<myType> myList = new List<myType>(someCapacity);
.
...populate the list with query from database...
.

var query = from i in myList
            select new
            {
                i.FieldA,
                i.FieldB,
                i.FieldC
            };

myBindingSource.DataSource = query;
myDataGrid.DataSource = myBindingSource;

Ensuite, je crée un objet DataGridTableStyle et l'ajoute à la grille de données. Cependant, elle n’applique jamais les propriétés de style de table que j’ai configurées car je ne peux pas sembler définir la propriété appropriée myDataGridTableStyle.MappingName.

J'ai cherché sur Google pendant environ une heure et demie et je voyais toujours des liens vers la même question sur plusieurs forums (littéralement le même texte, comme si quelqu'un copiait et collait la question ... Je déteste ça. ..). Quoi qu'il en soit, aucune des suggestions ne fonctionne, comme le dit le gars sur tous les autres sites.

Alors, est-ce que quelqu'un ici sait ce que je dois définir sur la propriété MappingName afin que mon TableStyle fonctionne réellement correctement? Où puis-je récupérer le nom? (Il ne peut pas être vide ... qui fonctionne uniquement avec un BindingSource lié à un DataTable ou à un SqlCeResultSet, etc.).

Je pense que l’utilisation de Linq pour créer une version anonyme et plus spécialisée des objets avec uniquement les champs dont j'ai besoin peut être un problème. Devrais-je simplement essayer de lier le BindingSource directement à l'objet List? Ou peut-être même lier le DataGrid directement à l'objet List et ignorer la source de liaison.

Merci

PS - C #, Compact Framework v3.5

MISE À JOUR:

J'ai posté une réponse ci-dessous qui a résolu mon problème. Que ce soit ou non la meilleure approche, cela a fonctionné. Ça vaut le coup d’y jeter un coup d’œil si vous avez le même problème que moi.

Était-ce utile?

La solution

J'ai trouvé le moyen de faire ce travail. Je vais le diviser en sections ...

List<myType> myList = new List<myType>(someCapacity);
.
...populate the list with query from database...
.
DataGridTableStyle myDataGridTableStyle = new DatGridtTableStyle();
DataGridTextBoxColumn colA = new DataGridTextBoxColumn();
DataGridTextBoxColumn colB = new DataGridTextBoxColumn();
DataGridTextBoxColumn colC = new DataGridTextBoxColumn();

colA.MappingName = "FieldA";
colA.HeaderText = "Field A";
colA.Width = 50; // or whatever;

colB.MappingName = "FieldB";
.
... etc. (lather, rinse, repeat for each column I want)
.

myDataGridTableStyle.GridColumnStyles.Add(colA);
myDataGridTableStyle.GridColumnStyles.Add(colB);
myDataGridTableStyle.GridColumnStyles.Add(colC);
var query = from i in myList
            select new
            {
                i.FieldA,
                i.FieldB,
                i.FieldC
            };

myBindingSource.DataSource = query.ToList(); // Thanks Marc Gravell

// wasn't sure what else to pass in here, but null worked.
myDataGridTableStyle.MappingName = myBindingSource.GetListName(null); 

myDataGrid.TableStyles.Clear(); // Recommended on MSDN in the code examples.
myDataGrid.TablesStyles.Add(myDataGridTableStyle);
myDataGrid.DataSource = myBindingSource;

Donc, fondamentalement, DataGridTableStyle.MappingName doit savoir à quel type d'objet il est mappé. Comme mon objet est de type anonyme (créé avec Linq), je ne sais pas ce que c'est avant la phase d'exécution. Après avoir lié la liste du type anonyme à la source de liaison, je peux utiliser BindingSource.GetListName (null) pour obtenir la représentation sous forme de chaîne du type anonyme.

Une chose à noter. Si je venais de lier la myList (qui est du type "myType") directement à la source de liaison, j'aurais pu simplement utiliser la chaîne "myType". comme valeur pour DataGridTableStyle.MappingName.

J'espère que cela sera utile à d'autres personnes!

Autres conseils

Juste pour ajouter à la collection de réponses déjà sur cette page ....

J'étais simplement frustré par ce même problème lorsque j'essayais de développer ma première application à l'aide de Windows Forms et d'un framework compact (Pour Windows Mobile 6.5).

Ce que j'ai découvert, à travers le commentaire de Marc Gravell ci-dessus, est qu'il est en effet possible d'obtenir l'exécution MappingName lors de l'exécution, en inspectant les propriétés du DataGrid. En faisant cela, j'ai découvert qu'en reliant mon List < MyType & directement à la propriété DataSource du DataGrid, le DataGrid recherchait en réalité un DataGridTableStyle avec le MappingName de

.
"List`1"

au lieu de toute combinaison de Liste < MonType & ou MonType ...

Alors ... en mettant "List`1" dans le nom de mappage de l'éditeur de collection DataGridTableStyle (au moment de la conception), j'ai pu personnaliser les colonnes et autres propriétés sans avoir à toutes les créer au moment de l'exécution.

J'espère seulement que cela ajoute un peu plus aux réponses déjà fournies. Merci à tous de m'avoir fourni les directives.

La requête retourne IEnumerable < T > pour un T , mais la plupart des sources de liaison (sauf ASP.NET) nécessitent IList (tel que toute implémentation IList < T > ) - essayez d'ajouter .ToList () - c'est-à-dire

myBindingSource.DataSource = query.ToList();

Un BindingList < T > pourrait fonctionner encore mieux (s'il est pris en charge dans CF 3.5) car il prend mieux en charge certains des scénarios de liaison courants; Si vous en avez besoin (et en supposant que BindingList < T > existe sur CF 3.5), vous pouvez ajouter une méthode d'extension:

static BindingList<T> ToBindingList<T>(this IEnumerable<T> data)
{
    return new BindingList<T>(new List<T>(data));
}

puis appelez:

myBindingSource.DataSource = query.ToBindingList();

Pour être complet, une alternative au IList est IListSource (ou même Type pour les scénarios contenant uniquement des métadonnées), raison pour laquelle DataSource est couramment saisi sous la forme objet ; S'il n'y avait pas eu ce problème, le compilateur aurait probablement pu vous dire le problème (c'est-à-dire si DataSource était défini comme IList ).

J'ai suivi cette réponse et découvert que le nom de classe sous-jacent était toujours le nom de mappage (myType dans l'exemple).

Il semble donc que le fait de placer la collection dans BindingSource résolve le problème de toute façon et qu’il n’est alors plus nécessaire de recourir à BindingSource.GetListName (null).

De plus, j’ai trouvé inutile d’ajouter à la requête ToList (), car BindingSource le fera également pour vous.

Merci beaucoup à Jason Down pour m'avoir mis sur la bonne voie.

Je rencontrais le même problème pour définir la largeur de la colonne. Après beaucoup de R & amp; D, j'ai changé le code comme ci-dessous et ça fonctionne bien. Code:

DataGridTableStyle tableStyle = new DataGridTableStyle();
tableStyle.MappingName = dgCustom.DataSource.GetType().Name;

dgCustom est l'ID de DataGrid dans dgCustom.DataSource.GetType (). Name qui fonctionne parfaitement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top