CultureInfo, Globalization, et Hashtable

CultureInfo, Globalization, et Hashtable - C#/.NET managed - Programmation

Marsh Posté le 21-11-2005 à 21:46:10    

Salut,
 
un petit truc rigolo qui m'est arrivé cette aprem au taf:
 
je développe (1 semaine d'experience sous .net/C++) une appli multilangue. Dans ce sens, j'utilise  
des objets Culture Info (string en parametre), et je tente d'implémenter la chose suivante:
 
- Un menu Language, avec ses objets menuItemFrench et menuItemEnglish.
- une méthode type evenement menuItem_Click (sender) qui réagit au click de l'un ou l'autre des menuItem, pour changer l'attribut Culture du thread principal (qui prend un string en parametre pour designer la langue courante, je répète).
- une hashtable qui contient en clé le menuItem et en value une valeur type "fr-FR" ou "en-US" selon le cas.
 
Ainsi, en fonction du sender, je voudrais chopper une string qui m'aiderait à instancier un objet CultureInfo.
 
Genre:
 


...
Hashtable->add(menuItemFrench,"fr-FR" );
Hashtable->add(menuItemEnglish,"en-US" );
...
void maForm::menuItem_onClick(sender *)  
{
String *s=__try_cast<String *>Hashtable->get_Item(sender);
monthread::gnignigni::CurrentCulture = new CultureInfo(s);
}


 
Le truc, c'est qu'en utilisant les ressources de l'IDE pour gérer les noms, les menuItem changent !!!
selon qu'on utilise les ressources fr ou en,  j'ai deux menuItemFrench (l'attribut menuID change !) et je ne peux retrouver ma string dans la hashtable.
(applause).
 
Alors j'ai tenté d'utiliser en clé l'attribut Index (ordre dans le menu) des menuItem, mais ca ne compile pas (la clé n'est pas accepté: type int non compatible avec <Objet __gc *> : WTF ?
 
Je ne sais pas si je suis clair, mais je donne tout renseignement à tout personne motivée pour me filer un coup de main parce que là, je suis agacé: je veux avoir quelque chose qui identifie mon menuItem de manière unique et public.

Reply

Marsh Posté le 21-11-2005 à 21:46:10   

Reply

Marsh Posté le 23-11-2005 à 20:47:45    

Grands dieux que tu te compliques la vie pour rien [:psychokwak]
Regarde donc du coté du ResourceManager, ça te simplifiera la vie


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 24-11-2005 à 09:03:58    

ben ouais ca se fait pas comme ca la "localisation"...

Reply

Marsh Posté le 26-11-2005 à 20:53:46    

Je m'en suis sorti, et j'utilisais déjà le ressource manager; il fallait juste que je puisse lire et écrire un fichier de config, savoir quelle langue on utilisait à un moment donné etc. Et pour pouvoir faire tout ça, il fallait passer par cette hashtable.

Reply

Marsh Posté le 27-11-2005 à 11:15:06    

j'en profite pour lancer le débat, c'est pas un peu chiant la localisation par des fichiers externes ? c'est-à-dire que dans le code on ne retrouve plus les chaines litérales, ça doit le rendre assez difficile à lire (du moins c'est ce que j'ai trouvé en regardant lucane).
 
est-ce qu'une notation du type "identifiant de chaine - chaine libre" (ex : "networkError - There were a network error" ) ne serait pas plus pratique ? ça existe déjà peut-être ?

Reply

Marsh Posté le 27-11-2005 à 12:59:49    

non c'est tres facile.

Reply

Marsh Posté le 27-11-2005 à 13:49:54    

nraynaud a écrit :

j'en profite pour lancer le débat, c'est pas un peu chiant la localisation par des fichiers externes ? c'est-à-dire que dans le code on ne retrouve plus les chaines litérales, ça doit le rendre assez difficile à lire (du moins c'est ce que j'ai trouvé en regardant lucane).
 
est-ce qu'une notation du type "identifiant de chaine - chaine libre" (ex : "networkError - There were a network error" ) ne serait pas plus pratique ? ça existe déjà peut-être ?


bah, sous .NET c'est comme ça que ça marche : tu créé un ResourceManager basé sur un fichier, lequel fichier aura le nom suivant :
nom.culture.resx, par exemple "strings.fr-FR.resx". les fichiers .resx dans ce cas sont des fichiers .resource contenant un identifiant de chaine, et la chaine traduite, le tout compilé avec ResGen.
 
tu créé donc un ResourceManager basé sur le fichier, mais en n'indiquant pas la culture :

Code :
  1. rm = ResourceManager.CreateFileBasedResourceManager("strings", path, null);


puis tu créé une CultureInfo, pour chaque traduction du fichier "strings.resx" :

Code :
  1. private CultureInfo frenchCulture = new CultureInfo("fr-FR" );
  2. private CultureInfo englishCulture = new CultureInfo("en-US" );


ceci suppose donc que tu possèdes 2 fichiers : strings.fr-FR.resx, et strings.en-US.resx.
 
et pour finir, tu changes de culture au besoin (par exemple, si l'utilisateur clique sur le menu permettant d'avoir toutes les chaines du soft en Anglais :

Code :
  1. Thread.CurrentThread.CurrentUICulture = englishCulture; // on utilise en-US
  2. cmdOK.Text = rm.GetString("cmdOK_Text" );


de cette façon, comme tu indiques que tu utiliser le CultureInfo en-US, le label de ton bouton sera récupéré à partir de l'identifiant "cmdOK_Text" présent dans ton fichier strings.en-US.resx.
ceci suppose évidemment que tous les identifiants soient identiques d'un fichier .resx à l'autre.
je vois donc pas ce qui te dérange avec les fichiers de localisation externes ?
 
tout comme je ne comprends donc pas pourquoi _darkalt3_ s'emmerde avec une hashtable et tout son bouzin, alors que tout se fait automatiquement de cette manière (cf mon plugin en signature, c'est comme ça que je l'ai localisé)

Message cité 1 fois
Message édité par Harkonnen le 27-11-2005 à 13:50:17

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 27-11-2005 à 17:34:42    

ben oui c'est comme ca qu'on fait [:spamafote]

Reply

Marsh Posté le 27-11-2005 à 18:16:54    

ben oui, que viennent donc faire les Hashtables ici ? :o


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 27-11-2005 à 22:31:51    

Citation :

c'est-à-dire que dans le code on ne retrouve plus les chaines litérales, ça doit le rendre assez difficile à lire (du moins c'est ce que j'ai trouvé en regardant lucane).
 
est-ce qu'une notation du type "identifiant de chaine - chaine libre" (ex : "networkError - There were a network error" ) ne serait pas plus pratique ? ça existe déjà peut-être ?


 
 

Harkonnen a écrit :


bah, sous .NET c'est comme ça que ça marche
(...)

Code :
  1. cmdOK.Text = rm.GetString("cmdOK_Text" );



superbe, tu viens de gagner un abonnement d'un an au cours de lecture de madame Martin prof de CP à l'école primaire Mermoz II de Taverny. Tu verras, elle est sympa et on apprend bien à lire avec elle.
 
 
 
J'pense que c'est tama qui a raison, ça doit pas être bien dur de wrapper le GetString par un parseur à pein plus compliqué, mais acceptant du bordel après l'identifieur.

Reply

Marsh Posté le 27-11-2005 à 22:31:51   

Reply

Marsh Posté le 28-11-2005 à 08:14:17    

j'ai toujours raison :o
 
Edit : Corollaire : je n'ai jamais tord [:vancrayenest]


Message édité par Tamahome le 28-11-2005 à 08:38:25
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed