Site logo
Site logo
Programmieren aus Leidenschaft
Programmieren aus Leidenschaft

XAML ContentStringFormat



Eine der Neuerungen im ServicePack 1 des Framework 3.5 ist die Möglichkeit, Zahlen direkt im XAML Code zu formatieren. In der Vergangenheit ging dies nur über Converter, die man im C# oder VB Code programmieren musste. Converter sind dabei ein sehr mächtiges Werkzeug, da man mit ihnen prinzipiell alle Werte und alle Typen konvertieren kann. Sie können einen boolschen Wert in eine Farbe konvertieren oder Zeichenketten auf vielerlei Arten manipulieren. Möchte man aber nur die Darstellung von Zahlen ändern, sind Converter inzwischen überflüssig, da diese Aufgabe durch ein StringFormat erledigt werden kann. Da ein StringFormat auch in Verbindung mit Databinding funktioniert, ist es ideal, um die Darstellung von Zahlenwerten optisch aufzuwerten.

Mit dem folgenden Code wird das Feld price vom Typ double an eine DataGrid Spalte gebunden. Eine ähnliche Anbindung wäre aber auch im einem TextField-Steuerelement möglich. Obwohl diese Anweisung perfekt funktioniert, lässt die Ausgabe doch etwas zu wünschen übrig, wie die Abbildung zeigt.
<dg:DataGridTextColumn Header="Price"
  CellStyle="{StaticResource RightAlignedCellStyle}"
  Width="100*" IsReadOnly="False" Binding="{Binding price}">
stacks_image_23C98F4B-AA32-4584-A32B-40B10E32EC5A
Schon durch Anhängen der Formatierung StringFormat=F2 erhalten alle Zahlen zwei Nachkommastellen. Dabei gehen aber keine Informationen verloren. Lediglich die Darstellung wird angepasst.
<dg:DataGridTextColumn Header="Price"
  CellStyle="{StaticResource RightAlignedCellStyle}"
  Width="100*" IsReadOnly="False" Binding="{Binding price,StringFormat=F2}">
stacks_image_3466F761-6D24-46A4-97BB-0012D32E8283
<dg:DataGridTextColumn Header="Price"
  CellStyle="{StaticResource RightAlignedCellStyle}"
  Width="100*" IsReadOnly="False" Binding="{Binding price}">
Möchte man hingegen auch Tausender-Trennzeichen darstellen, muss man sich einer anderen Formatierung bedienen, nämlich StringFormat=N2.
<dg:DataGridTextColumn Header="Price"
  CellStyle="{StaticResource RightAlignedCellStyle}"
  Width="100*" IsReadOnly="False" Binding="{Binding price,StringFormat=N2 }" >
stacks_image_A6A075CD-5542-47F7-8A77-EFCC38A62C3D
Die Trennzeichen sind jetzt alle dort, wo sie hingehören, leider sind sie, zumindest für deutschsprachige Systeme, nicht die Richtigen. Man muss der Umwandlung auch noch die für die Konvertierung zu benutzende Kultur mitteilen
<dg:DataGridTextColumn Header="Price"
      CellStyle="{StaticResource RightAlignedCellStyle}"
      Width="100*" IsReadOnly="False"
      Binding="{Binding price, ConverterCulture='de-DE', StringFormat=N2 }" >
Jetzt erhält man endlich eine korrekte Ausgabe. Eine Converter-Methode musste tatsächlich nicht geschrieben werden.
stacks_image_7DD94B2D-86BE-40CC-AE74-2D47BCA981BF
Dieser Lösungsweg ist natürlich mit Vorsicht zu geniessen, da jetzt die Kultur und damit auch das Zahlenformat fest vorgegeben sind. Sollte die Anwendung auch in anderen Kulturen zum Einsatz kommen, könnte die Formatierung die Anwender stören, da sie sich nicht automatisch den Landeseinstellungen anpasst.
Auch dieses Problem kann gelöst werden, allerdings ist es nicht mehr im XAML-Code machbar. Möchten Sie für die gesamte Anwendung die Kultur festlegen, so geht das am besten im statischen Konstuktor der Application.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using System.Windows.Markup;
using System.Globalization;


namespace DataGridApplication
{

    public partial class App : Application
    {
        static App()
        {
           FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement),
            new FrameworkPropertyMetadata(XmlLanguage.GetLanguage
           (CultureInfo.CurrentCulture.IetfLanguageTag)));
        }
    }
}
Mit dieser Anweisung wird die Sprache der Anwendung der im Betriebssystem eingestellten Kultur angepasst. Der Parameter ConverterCulture='de-DE' im Binding ist jetzt nicht mehr nötig.

Referenzen und weiterführende Informationen.
http://blogs.msdn.com/llobo/archive/2008/05/19/wpf-3-5-sp1-feature-stringformat.aspx
http://serialseb.blogspot.com/2007/04/wpf-tips-1-have-all-your-dates-times.html