Est-il possible de lier des propriétés de type complexes à une grid de données?

Comment ferais-je pour lier l’object suivant, Car, à un gridview?

 voiture de classe publique
 {
    id long {get;  ensemble;}
    Fabricant Maker {get;  ensemble;}
 }

 classe publique Fabricant
 {
    id long {get;  ensemble;}
    Nom de chaîne {get;  ensemble;}
 }

Les types primitifs sont liés facilement mais je n’ai trouvé aucun moyen d’afficher quoi que ce soit pour Maker. Je voudrais pour qu’il affiche le Manufacturer.Name. Est-ce même possible?

Quel serait un moyen de le faire? Devrais-je également stocker ManufacturerId dans Car, puis configurer un lookupEditRepository avec une liste de fabricants?

Très bien les gars … Cette question a été postée, mais je viens de trouver un moyen simple et agréable de le faire en utilisant la reflection dans l’événement cell_formatting pour récupérer les propriétés nestedes.

Va comme ça:

private void Grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { DataGridView grid = (DataGridView)sender; DataGridViewRow row = grid.Rows[e.RowIndex]; DataGridViewColumn col = grid.Columns[e.ColumnIndex]; if (row.DataBoundItem != null && col.DataPropertyName.Contains(".")) { ssortingng[] props = col.DataPropertyName.Split('.'); PropertyInfo propInfo = row.DataBoundItem.GetType().GetProperty(props[0]); object val = propInfo.GetValue(row.DataBoundItem, null); for (int i = 1; i < props.Length; i++) { propInfo = val.GetType().GetProperty(props[i]); val = propInfo.GetValue(val, null); } e.Value = val; } } 

Et c'est tout! Vous pouvez maintenant utiliser la syntaxe familière "ParentProp.ChildProp.GrandChildProp" dans le DataPropertyName pour votre colonne.

Oui, vous pouvez créer un TypeDescriptionProvider pour effectuer la liaison nestede. Voici un exemple détaillé tiré d’un blog MSDN:

http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column-to-a-second-level-property-of-a-data-source. aspx

La façon dont j’ai abordé cette question dans une application récente a été de créer mes propres classes DataGridViewColumn et DataGridViewCell héritant d’une des classes existantes telles que DataGridViewTextBoxColumn et DataGridViewTextBoxCell.

Selon le type de cellule que vous souhaitez, vous pouvez en utiliser d’autres, tels que Bouton, Case à cocher, ComboBox, etc. Il suffit de jeter un coup d’œil aux types disponibles dans System.Windows.Forms.

Les cellules traitent de leur valeur en tant qu’objects afin que vous puissiez passer votre classe Car dans la valeur de la cellule.

Remplacer SetValue et GetValue vous permettra d’avoir toute logique supplémentaire dont vous avez besoin pour gérer la valeur.

Par exemple:

 public class CarCell : System.Windows.Forms.DataGridViewTextBoxCell { protected override object GetValue(int rowIndex) { Car car = base.GetValue(rowIndex) as Car; if (car != null) { return car.Maker.Name; } else { return ""; } } } 

Sur la classe de colonne, la principale chose à faire est de définir le CellTemplate sur votre classe de cellule personnalisée.

 public class CarColumn : System.Windows.Forms.DataGridViewTextBoxColumn { public CarColumn(): base() { CarCell c = new CarCell(); base.CellTemplate = c; } } 

En utilisant ces colonnes / cellules personnalisées sur le DataGridView, il vous permet d’append de nombreuses fonctionnalités supplémentaires à votre DataGridView.

Je les ai utilisés pour modifier le formatage affiché en surchargeant GetFormattedValue pour appliquer un formatage personnalisé aux valeurs de chaîne.

J’ai également effectué un remplacement sur Paint afin de pouvoir personnaliser les cellules en fonction des conditions de valeur, en modifiant les cellules Style.BackColor en fonction de la valeur recherchée.

  public class Manufacturer { long Id {get; set;} Ssortingng Name {get; set;} public override ssortingng ToSsortingng() { return Name; } } 

Remplacez la méthode to ssortingng.

Utilisez simplement une liste et définissez le DataMember sur la chaîne “Maker.Name”. Si vous souhaitez que DataKeyField utilise l’ID de la voiture, définissez-le sur “ID”.

 dataGrid.DataSource = carList; dataGrid.DataMember = "Maker.Name"; dataGrid.DataKeyField = "ID"; dataGrid.DataBind(); 

Je sais que cela fonctionne dans le contrôle de répéteur, au moins …

Si vous souhaitez exposer des propriétés nestedes spécifiques en tant que cibles de liaison, alors la réponse de Ben Hoffstein ( http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column- to-a-second-level-property-of-a-data-source.aspx ) est très bonne. L’article référencé est un peu obtus, mais cela fonctionne.

Si vous souhaitez simplement lier une colonne à une propriété complexe (par exemple, Fabricant) et remplacer la logique de rendu, faites ce que ManiacXZ vous a recommandé ou créez simplement la sous-classe BoundField et fournissez une implémentation personnalisée de FormatDataValue (). Ceci est similaire à la redéfinition de ToSsortingng (); vous obtenez une référence d’object et vous retournez la chaîne que vous voulez afficher dans votre grid.

Quelque chose comme ça:

 public class ManufacturerField : BoundField { protected override ssortingng FormatDataValue(object dataValue, bool encode) { var mfr = dataValue as Manufacturer; if (mfr != null) { return mfr.Name + " (ID " + mfr.Id + ")"; } else { return base.FormatDataValue(dataValue, encode); } } } 

Ajoutez simplement un ManufacturerField à votre grid, en spécifiant “Fabricant” comme champ de données, et le tour est joué.

Voici une autre option que je travaille:

   <%#Eval("Maker.Name")%>   

Peut-être spécifique à ASP.NET 4.0 mais cela fonctionne à merveille!

Je suppose que vous pourriez faire ce qui suit:

 public class Car { public long Id {get; set;} public Manufacturer Maker {private get; set;} public ssortingng ManufacturerName { get { return Maker != null ? Maker.Name : ""; } } } public class Manufacturer { long Id {get; set;} Ssortingng Name {get; set;} }