2010-11-24 34 views
5

Je développe du code pour présenter des symboles monétaires dans le cadre d'une étiquette sur mon application, et j'ai une liste de référence de symboles monétaires au format hexadécimal Unicode. Dans mon code, je suis mise en forme de la monnaie comme suit:Placement de symboles de devise dans les chaînes .NET

(symbole monétaire) (chaîne décimale) (description de la monnaie)

Cette approche fonctionne très bien pour la plupart des symboles, mais je remarque que certains des symboles sont automatiquement décalé vers la droite de la valeur décimale même si explicitement placé à gauche. En utilisant le débogueur, je vois ce comportement même au niveau le plus fondamental dans les chaînes elles-mêmes, donc ce n'est pas un cas de manipulation à des niveaux plus élevés par le rendu dans la couche de présentation. Le code suivant présente le cas simple montrant le problème:

string rialSymbol = "\ufdfc"; 
string amount = "123.45"; 
string description = "Rials"; 
string plainConcat = rialSymbol + " " + amount + " " + description; 
Debug.WriteLine(plainConcat); 

La sortie de débogage (qui correspond également à ce qui est vu dans l'interface utilisateur de l'application) est comme suit:

123,45 (symbole rial) rials

(Note: le symbole est à la droite de la décimale, pas la gauche, comme spécifié)

J'ai essayé plusieurs approches et variétés de mise en forme de chaînes, mise en forme de culture, etc., mais rien ne semble résoudre ce problème. Comment puis-je appliquer le placement du caractère Unicode sans que le cadre ne décide du positionnement du symbole par rapport à la valeur décimale? Cela fonctionne avec la plupart des autres personnages, pourquoi le Rial (et quelques autres) provoque ce type de comportement de chaîne fondamentale?

Répondre

9

U+FDFC est un caractère Unicode de droite à gauche. Il est destiné à être intégré dans un texte de droite à gauche. Vous mélangez le texte de gauche à droite et de droite à gauche.

De Wikipedia:

Dans le codage Unicode, tous les caractères non ponctuation sont stockés dans l'ordre d'écriture. Cela signifie que la direction d'écriture des caractères est stockée dans les caractères. Si c'est le cas, le personnage est appelé "fort". Les caractères de ponctuation peuvent cependant apparaître dans les scripts LTR et RTL. Ils sont appelés caractères "faibles" car ils ne contiennent aucune information directionnelle. Il appartient donc au logiciel de décider dans quelle direction ces caractères "faibles" seront placés. Parfois (dans le texte à directions mélangées) cela conduit à des erreurs d'affichage, causées par l'algorithme bidi qui parcourt le texte et identifie les caractères forts LTR et RTL et attribue une direction aux caractères faibles, selon les règles de l'algorithme.

Dans l'algorithme, chaque séquence de caractères forts concaténés est appelée "exécution". Un caractère faible situé entre deux caractères forts de même orientation héritera de leur orientation. Un caractère faible situé entre deux caractères forts avec une direction d'écriture différente héritera de la direction d'écriture du contexte principal (dans un document LTR, le caractère deviendra LTR, dans un document RTL, il deviendra RTL). Si un caractère "faible" est suivi d'un autre caractère "faible", l'algorithme regarde le premier caractère "fort" voisin. Parfois, cela entraîne des erreurs d'affichage involontaires. Ces erreurs sont corrigées ou empêchées avec des caractères "pseudo-forts". Ces caractères de contrôle Unicode sont appelés marques. La marque U + 200E (marque de gauche à droite) ou U + 200F (marque de droite à gauche) doit être insérée dans un emplacement pour faire en sorte qu'un caractère faible enfermé hérite de sa direction d'écriture.Par exemple, pour afficher correctement le signe de la marque commerciale U + 2122 ™ pour un nom anglais (LTR) dans un passage arabe (RTL), une marque LRM est insérée après le symbole de la marque si le symbole n'est pas suivi. par le texte LTR. Si la marque LRM n'est pas ajoutée, le personnage faible sera voisin d'un personnage LTR fort et d'un personnage RTL fort. Par conséquent, dans un contexte RTL, il sera considéré comme RTL et affiché dans un ordre incorrect.

La solution est donc d'ajouter un U + 200E gauche à droite marque après les symboles monétaires de droite à gauche:

string rialSymbol = "\ufdfc\u200e"; 
string amount = "123.45"; 
string description = "Rials"; 
string plainConcat = rialSymbol + " " + amount + " " + description; 
Debug.WriteLine(plainConcat); 
+0

Merci beaucoup! Exactement ce dont j'avais besoin. – DMG

+0

+1 Wow, d'où cela vient-il ?! Incroyable ... – Aliostad

+0

J'ai trouvé les détails de l'algorithme BiDi ici: http://www.unicode.org/reports/tr9/ – DMG