Changement de l'Attribut de paramètre lors de l'exécution
Je ne suis pas sûr de savoir si c'est possible de changer l'attribut de paramètre au cours de l'exécution? Par exemple, à l'intérieur d'une assemblée j'ai la classe suivante
public class UserInfo
{
[Category("change me!")]
public int Age
{
get;
set;
}
[Category("change me!")]
public string Name
{
get;
set;
}
}
C'est une classe qui est fourni par un fournisseur tiers et je ne peux pas changer le code. Mais maintenant j'ai trouvé que les descriptions ne sont pas exacts, et je veux changer le "change me" nom de la catégorie à autre chose quand je le lier à une instance de la classe ci-dessus à une propriété de la grille.
Pouvez-vous me dire comment faire cela?
Vous devez vous connecter pour publier un commentaire.
Bien vous apprendre quelque chose de nouveau chaque jour, apparemment j'ai menti:
http://www.vsj.co.uk/articles/display.asp?id=713
Au cas où quelqu'un d'autre marche le long de cette avenue, la réponse est que vous pouvez le faire, avec la réflexion, à l'exception que vous ne pouvez pas car il y a un bug dans le cadre. Voici comment faire:
Tout va bien, sauf que la catégorie d'attribut est modifié pour toutes les propriétés, et pas seulement "Âge".
Vous pouvez sous-classe la plupart des attributs communs assez facilement pour fournir cette extensibilité:
Il y a des options plus complexes qui impliquent l'écriture personnalisée
PropertyDescriptor
s, exposée parTypeConverter
,ICustomTypeDescriptor
ouTypeDescriptionProvider
- mais qui est généralement exagéré.Malheureusement, les attributs ne sont pas destinées à changer lors de l'exécution. En gros, vous avez deux options:
Recréer un type similaire à la volée à l'aide de
System.Reflection.Emit
comme indiqué ci-dessous.Demandez à votre fournisseur pour ajouter cette fonctionnalité. Si vous utilisez Xceed.WpfToolkit.Étendue vous pouvez télécharger le code source de ici et facilement mettre en œuvre une interface comme
IResolveCategoryName
qui permettrait de résoudre l'attribut au moment de l'exécution. J'ai fait un peu plus que cela, il était assez facile d'ajouter plus de fonctionnalités, comme des limites lors de la modification d'une valeur numérique dans uneDoubleUpDown
à l'intérieur de laPropertyGrid
, etc.Pour la première option: néanmoins le manque de bonne propriété de liaison afin de refléter le résultat de retour de l'objet réel en cours d'édition.
Avez-vous résolu le problème?
Ici sont les mesures possibles pour parvenir à une solution acceptable.
[Category]
attribut (marquer avecnew
). Exemple:Plus tard Edit: Cette partie de la solution n'est pas réalisable si vous avez un grand nombre de propriétés que vous pourriez avoir besoin de réécrire les attributs. C'est là que la deuxième partie se met en place:
Étant donné que la grille des propriétés de l'élément sélectionné est "l'Âge":
Où
SetCategoryLabelViaReflection()
est définie comme suit:Autant que par programmation réglage de l'élément sélectionné, le parent de la catégorie dont vous souhaitez changer; il y a un certain nombre de solutions simples. Google "Définir le Focus à une grille de propriété à la propriété".
Je ne le pense vraiment pas, à moins qu'il y a un peu funky réflexion qui peut le retirer. La propriété décorations sont définies au moment de la compilation et à ma connaissance, sont fixés
Dans le temps de le dire, je suis venu pour une solution partielle, dérivée à partir des articles suivants:
Fondamentalement, vous devez créer une classe générique
CustomTypeDescriptorWithResources<T>
, qui permettrait d'obtenir les propriétés de la réflexion et de la chargeDescription
etCategory
à partir d'un fichier (je suppose que vous avez besoin pour afficher le texte localisé afin que vous pouvez utiliser un fichier de ressources (.resx
))Voici une "cheaty" façon de le faire:
Si vous avez un nombre fixe de potentiel constante des valeurs pour le paramètre d'attribut, vous pouvez définir une propriété distincte pour chaque potentiel de la valeur du paramètre (et donner à chacun le bien que légèrement différente de l'attribut), puis passer la propriété de qui vous de référence de façon dynamique.
Dans VB.NET il pourrait ressembler à ceci:
Vous pouvez modifier les valeurs d'Attribut au moment de l'exécution au niveau de la Classe (pas d'objet):