2010-11-24 7 views
5

Ich entwickle Code, um Währungssymbole als Teil eines Labels in meiner Anwendung darzustellen, und ich habe eine Referenzliste mit Währungssymbolen im Unicode-Hexadezimalformat. In meinem Code bin Formatierung ich die Währung wie folgt:Platzierung von Währungssymbolen in .NET-Zeichenfolgen

(Währungssymbol) (Dezimalstring) (Währung Beschreibung)

Dieser Ansatz funktioniert für die meisten Symbole in Ordnung, aber merke ich, dass einige der Symbole wird automatisch nach rechts vom Dezimalwert verschoben, auch wenn explizit nach links platziert. Wenn ich den Debugger benutze, sehe ich dieses Verhalten sogar auf der grundlegendsten Ebene in den Strings selbst, so dass hier keine Manipulation auf höheren Ebenen durch das Rendering in der Präsentationsebene stattfindet. Der folgende Code stellt den einfachen Fall zeigt das Problem:

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

Die Debug-Ausgabe (die auch dem entspricht, was in der Anwendung UI gesehen hat) ist wie folgt:

123,45 (rial Symbol) Rials

(Hinweis: Das Symbol ist rechts neben der Dezimalzahl nicht links, wie angegeben)

Ich habe viele Ansätze und Varianten der String-Formatierung, Kulturformatierung usw. versucht, aber nichts scheint dieses Problem anzugehen. Wie kann ich die Platzierung des Unicode-Zeichens erzwingen, ohne dass das Framework die Platzierung des Symbols relativ zum Dezimalwert entscheidet? Dies funktioniert mit den meisten anderen Zeichen, warum verursacht der Rial (und einige andere) diese Art von grundlegendem String-Verhalten?

Antwort

9

U+FDFC ist ein Rechts-nach-links-Unicode-Zeichen. Es soll in Text von rechts nach links eingebettet werden. Sie mischen Text von links nach rechts und von rechts nach links.

Von Wikipedia:

In Unicode-Codierung, alle Nicht-Interpunktionszeichen werden schriftlich Reihenfolge gespeichert. Dies bedeutet, dass die Schreibrichtung von Zeichen innerhalb der Zeichen gespeichert wird. Wenn dies der Fall ist, wird das Zeichen "stark" genannt. Interpunktionszeichen können jedoch sowohl in LTR- als auch in RTL-Skripts angezeigt werden. Sie werden "schwache" Zeichen genannt, da sie keine Richtungsinformationen enthalten. Es liegt also an der Software zu entscheiden, in welche Richtung diese "schwachen" Zeichen gesetzt werden. Manchmal (in gemischtem Text) führt dies zu Anzeigefehlern, die durch den Bidi-Algorithmus verursacht werden, der den Text durchläuft und starke Zeichen von LTR und RTL identifiziert und schwachen Zeichen gemäß den Regeln des Algorithmus eine Richtung zuweist.

Im Algorithmus wird jede Folge von verketteten starken Zeichen als "run" bezeichnet. Ein schwaches Zeichen, das sich zwischen zwei starken Zeichen mit der gleichen Ausrichtung befindet, erbt ihre Ausrichtung. Ein schwaches Zeichen, das sich zwischen zwei starken Zeichen mit einer anderen Schreibrichtung befindet, erbt die Schreibrichtung des Hauptkontexts (in einem LTR-Dokument wird das Zeichen zu LTR, in einem RTL-Dokument wird es zu RTL). Wenn ein "schwaches" Zeichen von einem anderen "schwachen" Zeichen gefolgt wird, wird der Algorithmus auf das erste benachbarte "starke" Zeichen schauen. Manchmal führt dies zu unbeabsichtigten Anzeigefehlern. Diese Fehler werden mit "pseudo-starken" Zeichen korrigiert oder verhindert. Solche Unicode-Steuerzeichen heißen Markierungen. Die Markierung U + 200E (Markierung von links nach rechts) oder U + 200F (Markierung von rechts nach links) wird an einer Stelle eingefügt, an der ein eingeschlossenes schwaches Zeichen seine Schreibrichtung erbt.

Um beispielsweise das U + 2122 ™ Markenzeichen für eine englische Markenmarke (LTR) in einer arabischen (RTL) Passage korrekt anzuzeigen, wird nach dem Markenzeichen eine LRM Marke eingefügt, wenn das Symbol nicht befolgt wird nach LTR-Text. Wenn das LRM-Zeichen nicht hinzugefügt wird, wird das schwache Zeichen TM von einem starken LTR-Zeichen und einem starken RTL-Zeichen umgeben sein. Daher wird es in einem RTL-Kontext als RTL betrachtet und in einer falschen Reihenfolge angezeigt.

So ist die Lösung eine U + 200E von links nach rechts Markierung nach rechts nach links Währungssymbole hinzuzufügen:

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

vielen Dank! Genau das, was ich brauchte. – DMG

+0

+1 Wow, woher kam das ?! Erstaunlich ... – Aliostad

+0

Ich fand die Details des BiDi-Algorithmus hier: http://www.unicode.org/reports/tr9/ – DMG