Je suis confronté à un problème que je ne sais pas comment résoudre et espérons que la communauté peut aider.
J'écris une application qui gère des objets "plomb". (Ce sont des pistes de vente.) Une partie de mon programme importera des pistes d'un fichier texte. Maintenant, le fichier texte contient de nombreux prospects potentiels, dont je voudrais importer et certains dont je ne le ferai pas. P>
pour faciliter la programmation (et l'utilisation), je l'analyse du texte Fichier dans une liste Ce que je veux faire est d'ajouter une colonne à la grille, appelée "importation, "Avec une case à cocher que l'utilisateur peut vérifier si chaque plomb doit être importé ou non. P> Ma première pensée consiste à dériver une classe de plomb:
public LeadWithImportCheckbox(Lead newlead)
{
base.Property1 = newlead.Property1;
base.Property2 = newlead.Property2;
....
base.Property_n = newlead.Property_n;
}
11 Réponses :
Ce que vous voulez faire est d'afficher la colonne Cochez la case de votre réseau et ne l'avez pas connectée à vos objets en plomb. Vous utilisez les colonnes marquées (et la liste d'origine) pour créer un nouvel ensemble de liste qui sera votre liste d'importation.
puis gérer tout ce que vous souhaitez faire avec la liste nouvellement créée. P>
modifier : Une chose à faire preuve de prudence lorsque vous travaillez avec des listes, c'est le fait que chaque objet de classe n'est en réalité qu'un pointeur de la classe, donc si vous travaillez avec la liste d'origine et que vous faites quelque chose comme: p> que des objets existeront dans les deux listes et si vous modifiez des données d'un dirige sur l'une ou l'autre liste sera modifiée. P> P>
J'ai demandé à l'origine cette solution. Cela fonctionne de manière appropriée si j'utilise une liste
public class LeadListItem { public Lead Lead { get; set; } public bool ShouldImport { get; set; } } i.e. don't copy the Lead object's contents, just store a reference to it in a new LeadListItem object, which adds extra info "outside" the original object.If you want the properties of Lead to appear in the grid, there is almost certainly a way of doing that. Why not ask that question, instead of downvoting me for telling you the right answer to this question!
Le problème avec cette solution est que les membres de plomb ne se présentent pas dans la DataGridView.
@Le Demigeek Voulez-vous, mais c'est une question différente.
Greenreign, comment est-ce une question différente? La question initiale portait sur l'affichage d'une avance avec une case à cocher dans un DataGridView. Une solution qui n'inclut pas les membres du plomb dans la DataGridView n'est pas une solution au problème.
La solution correcte à votre problème consiste à modéliser les données judicieusement avec des objets, puis à indiquer à la grille comment présenter le modèle afin qu'il affiche toutes les parties dont vous avez besoin. Ma réponse est la bonne réponse à la première partie, maintenant, vous devez trouver la deuxième partie. Cette deuxième partie est une question distincte.
@Le Demigeek ah, d'accord. Je vois maintenant, c'est ce que vous avez noté.
Pour l'énoncer succinctement, "préfère la composition sur l'héritage"
Earwicker fait un très bon point. Considérant que vous avez au moins 4 réponses qui copient essentiellement le sien, j'y penserais plus ... mais vous avez vos raisons, alors ...
Quelques options que vous avez peut-être manquées: p>
J'irais avec la création d'une propriété d'importation sur la classe principale elle-même
Beaucoup plus éloquemment déclaré que ma tentative maladroite ci-dessus, mais à peu près ce que j'essayais de dire.
Je devrais être en désaccord avec Stan. Il n'y a aucune raison de la propriété d'importation sur la tête, elle est totalement sans rapport avec la tête et la pollution de votre objet de domaine. Ce n'est qu'un artefact de l'interface utilisateur et il ne faut donc pas modifier les objets de votre domaine de toute façon.
Vous ne pouvez que baisser uniquement, si l'objet à baisser est vraiment em> un objet de ce type. Un moyen plus facile de résoudre votre problème serait d'avoir une classe DisplayLead, telle que: p> qui vous aiderait également à séparer les données stockées de leur représentation dans une interface graphique. p> p>
Si je fais cela, les propriétés du plomb ne vous apparaissent pas dans la DataGridView.
Avec les informations que vous avez fournies en réponse à mon message, c'est la solution optimale. Ce que vous devez faire est d'éteindre les colonnes de générer automatiquement et de créer manuellement les colonnes et d'utiliser des expressions de base de données pour atteindre les éléments de conteneur réels afin de pouvoir lire des objets complexes. Si vous recherchez C # DataBinding Eval ou similaire dans Google, vous devriez voir comment le faire.
En tant que solution rapide et sale, vous pouvez créer votre objet "Cochez la case" comme objet différent contenant une instance de plomb. de cette façon, vous pouvez facilement ajouter plus de "grille" Propriétés à cet objet, tout en conservant toujours une référence aux détails de la tête sans cloner de la propriété du code papier. P> P>
Si je fais cela, les propriétés du plomb ne vous apparaissent pas dans la DataGridView.
vous recommande d'essayer de modifier (mettre à niveau) vos objets de plomb importés. P>
Essayez de commencer par les exemples ici ... p>
Je ne peux pas descendre à quelque chose que ce n'est pas le cas. Si l'objet a été instancié sous la forme d'un ProTrip: Type de contrôle au moment de l'exécution avec dirigeant code>, il ne peut pas être bumé à une classe dérivée. S'il était instancié sous la forme d'un
LeadwithimportCheckbox code> puis retourné à votre code sous forme
lead code>, vous pouvez le refuser. P>
est code> opérateur. p>
Si votre classe de plomb possédait un constructeur de copie (par exemple, le plomb (p. Extra enfermé) "), leadwithimportCheckbox hériterait et vous pouvez simplement appeler le constructeur principal de base dans le constructeur duadwithImpportCheckbox - Par conséquent, aucun besoin de leadwithImpportCheckBeCheckBeCKECKECKECKECKECKE détails de plomb. p>
Il y a de nombreuses façons de faire cela, mais la «bonne» façon apparaît à cause de ce que vous avez dit, ici:
Pour faciliter la programmation (et l'utilisation), je suis analyser le fichier texte dans un Liste d'objet, et à l'aide d'un DataGridView pour afficher les prospects par Définition de la propriété DataSource de la DataGridView. P>
Ce que je veux faire, c'est ajouter une colonne à la grille, appelée "importation" avec un case à cocher que l'utilisateur peut vérifier à indiquer si chaque avance ou non devrait être importé. P> blockquote>
Votre
Lead code> L'objet se situe bien seul et vous souhaitez attacher des métadonnées à celle-ci - vous ne voulez pas créer un autre fichier
code> Classification (c.-à-d. Le
LeadwithimportCheckbox Code> Classe). P>
Ainsi, la meilleure approche dans votre cas consiste à avoir une classe comme: p>
xxx pré> Ceci va bien augmenter lorsque vous souhaitez ajouter plus de métadonnées à votre liste, comme si vous souhaitez vous envoyer des rappels de courrier électronique à leur sujet chaque semaine. p> p>
Mais si je fais cela, les propriétés principales ne s'affichent pas sur la DataGridView.
ou, pour éviter l'aspect pita, utilisez la réflexion ... (essayez ceci ...)
Modifier: Utilisez la propriété, pas de champ comme je l'avais initialement écrit ... p>
public class NewLead : Lead { public bool Insert; public NewLead(Lead lead, bool insert) { Insert = insert; foreach (PropertyInfo pi in typeof(Lead).GetProperties()) GetType().GetProperty(pi.Name).SetValue (this, pi.GetValue(lead,null), null); } }
Je pense qu'en fin de compte j'aime l'approche de réflexion. (Je ne manque pas de la compréhension.) Dans votre code d'échantillon, je reçois un tableau de longueur zéro de typeof (plomb) .tfields ()
Je crois que c'est la solution que je vais m'installer. Merci, Charles! Le code que j'ai mis en œuvre et qui semble fonctionner est:
Solution fantastique. J'aime ne pas avoir à mettre à jour manuellement mon constructeur si la classe de base change.
J'ai vu la solution correcte répertorie tant de fois que je me sens comme un talon qui le pose à nouveau, mais le meilleur moyen d'aborder cela consiste à écrire une enveloppe pour l'objet principal qui inclut le drapeau d'importation. P>
Si les propriétés de l'objet LEAD n'apparaissent pas dans la grilleView car vous êtes en train de diffuser sur l'objet, écrivez ensuite des propriétés passées qui reflètent les propriétés principales de l'objet wrapper. P>
Le problème est que vous souhaitez que quelque chose affiche à l'utilisateur qui ne soit pas une partie inhérente du modèle de données. La réponse consiste à envelopper les données avant de la présenter à l'utilisateur afin que vous puissiez contrôler ce qu'ils voit sans changer le modèle sous-jacent. P>
Si vous craignez que l'objet principal puisse changer tant de fois à l'avenir que des modifications apportées à l'enveloppe seront encombrantes, vous pouvez examiner la génération de code dynamique basée sur l'objet principal qui générera automatiquement un objet wrapper avec le mêmes champs que l'objet principal plus le drapeau d'importation. Bien que franchement, c'est beaucoup plus de travail que vous aurez probablement besoin de quelque chose de plus simple que cela. P>
Je ne crois pas que ce soit la solution optimale. Si la structure de l'objet de plomb sous-jacent change, je dois revenir en arrière et éditer le code qui lie les propriétés de la direction à la DataGridView. L'héritage résout ce problème. Peu importe les changements apportés à mener, si leadwithimportCheckbox hérite de plomb, alors je n'ai pas besoin de modifier de code. Et «leadthatimightwanttoimport 'est-un« plomb ». L'héritage est approprié. Je crois que l'utilisation de la réflexion, comme le suggère Charles, sera la bonne façon de créer une boîte de plomb de plombhithimportcheck.
L'approche de réflexion atténuerait la question des «changements d'objet principal sous-jacents», mais comme je l'ai dit, si votre objet principal change cela souvent, il existe souvent des problèmes plus profonds que vos pratiques de codage. Sur la base de votre réponse à la solution de Charles, je ne suis pas sûr que la réflexion sera la bonne façon de vous assurer non plus. Notez également que l'utilisation de la réflexion de cette manière imposera une pénalité de performance grave (pourrait être un problème si vous commencez à avoir plusieurs milliers de prospects).
Juste une pensée aléatoire: est-il possible que vous souhaitiez suivre si un plomb était «importé» ou non (entré à la main)? En d'autres termes, pourrait-il être utile de faire
importé code> une propriété permanente de
dirige code>?
Je ne pense pas que ce soit quelque chose que je voudrais suivre. Je vois les problèmes que cela résoudrait, mais cela ne fait vraiment pas partie de ce que je veux vraiment accomplir.