Je recherche un moyen de localiser les noms de propriétés affichés dans un PropertyGrid. Le nom de la propriété peut être «remplacé» à l'aide de l'attribut DisplayNameAttribute. Malheureusement, les attributs ne peuvent pas avoir d'expressions non constantes. Je ne peux donc pas utiliser de ressources fortement typées telles que:
class Foo
{
[DisplayAttribute(Resources.MyPropertyNameLocalized)] // do not compile
string MyProperty {get; set;}
}
J'ai jeté un coup d'œil et j'ai trouvé une suggestion pour hériter de DisplayNameAttribute pour pouvoir utiliser la ressource. Je finirais avec un code comme:
class Foo
{
[MyLocalizedDisplayAttribute("MyPropertyNameLocalized")] // not strongly typed
string MyProperty {get; set;}
}
Cependant, je perds des avantages de ressources fortement typés, ce qui n'est certainement pas une bonne chose. Ensuite, je suis tombé sur DisplayNameResourceAttribute qui est peut-être ce que je recherche. Mais il est censé être dans l'espace de noms Microsoft.VisualStudio.Modeling.Design et je ne trouve pas la référence que je suis censé ajouter pour cet espace de noms.
Quelqu'un sait-il s'il existe un moyen plus simple de parvenir à la localisation DisplayName d'une bonne manière? ou s'il existe un moyen d'utiliser ce que Microsoft semble utiliser pour Visual Studio?
la source
Réponses:
Il existe l' attribut Display de System.ComponentModel.DataAnnotations dans .NET 4. Il fonctionne sur le MVC 3
PropertyGrid
.Cela recherche une ressource nommée
UserName
dans votreMyResources
fichier .resx.la source
typeof(MyResources)
, vous devrez peut-être définir votre modificateur d'accès au fichier de ressources sur Public .Nous faisons cela pour un certain nombre d'attributs afin de prendre en charge plusieurs langues. Nous avons adopté une approche similaire à Microsoft, où ils remplacent leurs attributs de base et transmettent un nom de ressource plutôt que la chaîne réelle. Le nom de la ressource est ensuite utilisé pour effectuer une recherche dans les ressources DLL pour la chaîne réelle à renvoyer.
Par exemple:
Vous pouvez aller plus loin lorsque vous utilisez réellement l'attribut et spécifier vos noms de ressources en tant que constantes dans une classe statique. De cette façon, vous obtenez des déclarations comme.
La mise à jour
ResourceStrings
ressemblerait à quelque chose comme (note, chaque chaîne ferait référence au nom d'une ressource qui spécifie la chaîne réelle):la source
[MyNamespace].[MyResourceFile].ResourceManager.GetString("MyString");
Voici la solution avec laquelle je me suis retrouvé dans un assemblage séparé (appelé "Common" dans mon cas):
avec le code pour rechercher la ressource:
L'utilisation typique serait:
Ce qui est assez laid car j'utilise des chaînes littérales pour la clé de ressource. Utiliser une constante signifierait modifier Resources.Designer.cs, ce qui n'est probablement pas une bonne idée.
Conclusion: je ne suis pas satisfait de cela, mais je suis encore moins satisfait de Microsoft qui ne peut rien fournir d'utile pour une tâche aussi courante.
la source
ResourceManager
propriétés. Au lieu de cela, vous pouvez simplement obtenir la propriété directement à partir du type fourni dans le paramètre:PropertyInfo property = resourceManagerProvider.GetProperty(resourceKey, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
En utilisant l' attribut Display (de System.ComponentModel.DataAnnotations) et l' expression nameof () en C # 6, vous obtiendrez une solution localisée et fortement typée.
la source
Vous pouvez utiliser T4 pour générer des constantes. J'en ai écrit un:
la source
C'est une vieille question, mais je pense que c'est un problème très courant, et voici ma solution dans MVC 3.
Tout d'abord, un modèle T4 est nécessaire pour générer des constantes afin d'éviter les chaînes désagréables. Nous avons un fichier de ressources 'Labels.resx' contenant toutes les chaînes d'étiquettes. Par conséquent, le modèle T4 utilise directement le fichier de ressources,
Ensuite, une méthode d'extension est créée pour localiser le 'DisplayName',
L'attribut 'DisplayName' est remplacé par l'attribut 'DisplayLabel' afin de lire automatiquement à partir de 'Labels.resx',
Après tout ce travail de préparation, il est temps de toucher ces attributs de validation par défaut. J'utilise l'attribut "Obligatoire" comme exemple,
Maintenant, nous pouvons appliquer ces attributs dans notre modèle,
Par défaut, le nom de la propriété est utilisé comme clé pour rechercher «Label.resx», mais si vous le définissez via «DisplayLabel», il l'utilisera à la place.
la source
Vous pouvez sous-classer DisplayNameAttribute pour fournir i18n, en remplaçant l'une des méthodes. Ainsi. edit: Vous devrez peut-être vous contenter d'utiliser une constante pour la clé.
la source
J'utilise cette façon résoudre dans mon cas
Avec le code
la source
Eh bien, l'assemblée l'est
Microsoft.VisualStudio.Modeling.Sdk.dll
. qui est fourni avec le SDK Visual Studio (avec le package d'intégration Visual Studio).Mais il serait utilisé à peu près de la même manière que votre attribut; il n'y a aucun moyen d'utiliser fortement des ressources de types dans les attributs simplement parce qu'elles ne sont pas constantes.
la source
Je m'excuse pour le code VB.NET, mon C # est un peu rouillé ... Mais vous aurez l'idée, non?
Tout d'abord, créez une nouvelle classe
LocalizedPropertyDescriptor
:, qui héritePropertyDescriptor
. Remplacez laDisplayName
propriété comme ceci:Some.ResourceManager
est le ResourceManager du fichier de ressources qui contient vos traductions.Ensuite, implémentez
ICustomTypeDescriptor
dans la classe avec les propriétés localisées et remplacez laGetProperties
méthode:Vous pouvez maintenant utiliser l'attribut 'DisplayName` pour stocker une référence à une valeur dans un fichier de ressources ...
prop_description
est la clé du fichier de ressources.la source