Entwickler-Ecke

WPF / Silverlight - Binding und StringFormat?


lord_fritte - Do 20.05.10 10:37
Titel: Binding und StringFormat?
Hallo ich möchte ein Label an ein Property binden welches mir ein DateTime Objekt zurück gibt.
Das möchte ich gerne Formatieren im G Format(20.05.2010 11:35:43.
Also habe ich mit dem StringFormat gespielt aber nichts hat geklappt, ich habe es so versucht:
{Binding Source={MyDate, StringFormat=G}
oder auch so:
{Binding Source={MyDate, StringFormat={}{0:G}}
und auch so:
{Binding Source={MyDate, StringFormat=\{0:G\}}
Aber bei allen 3 Variantent sah das Ergebnis so aus: 20.05.2010 11:35


Kha - Do 20.05.10 12:32

Äh, deine Syntax wird er erst gar nicht kompilieren, steht das wirklich so in deinem Quelltext? So funktioniert es jedenfalls:

XML-Daten
1:
2:
3:
4:
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="{Binding StringFormat=G}" />


C#-Quelltext
1:
2:
3:
4:
5:
    public MainWindow()
    {
      InitializeComponent();
      DataContext = DateTime.Now;
    }


lord_fritte - Do 20.05.10 12:35

MyDate ist ein DependencyProperty und im Konstruktor wird DataContext mit this belegt.


Kha - Do 20.05.10 12:38

Na dann gibt es eigentlich keinen Unterschied mehr zu meinem Beispiel, sobald du die öffnende geschweifte Klammer nach Source entfernst.


lord_fritte - Do 20.05.10 12:53

Ne es geht aber nicht!

Hier ist mal mein ganzer Code:
XAML:

XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
<Window x:Class="StringFormatTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel Orientation="Vertical">
        <Label Content="{Binding MyDate, StringFormat=G}" />
        <Label Content="{Binding MyDate, StringFormat={}{0:G}}" />
        <Label Content="{Binding MyDate, StringFormat=\{0:G\}}" />
    </StackPanel>
</Window>


CS:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
public partial class MainWindow : Window
  {
    public static readonly DependencyProperty MyDateProperty = DependencyProperty.Register("MyDate"typeof(DateTime), typeof(MainWindow), new PropertyMetadata(DateTime.Now));

    public MainWindow()
    {
      InitializeComponent();
      DataContext = this;
    }

    public DateTime MyDate
    {
      get { return (DateTime)GetValue(MyDateProperty); }
      set { SetValue(MyDateProperty, value); }
    }
  }


Aber in allen 3 Zeilen sieht die Ausgabe so aus: 20.05.2010 11:35
Also es wurde nichts formatiert.


Kha - Do 20.05.10 13:16

Da hast du dir aber einen schönen Corner Case herausgesucht :) . Content ist vom Typ object, also denkt das Binding gar nicht daran, DateTime in einen String zu konvertieren und dabei den Format-String anzuwenden. Wenn du wirklich ein Label brauchst, musst du einen TextBlock als Content setzen und an dessen Text-DP binden.


lord_fritte - Do 20.05.10 13:23

Ahh sag das doch, aber sucht das Binding dann nicht nach einem IFormattable Interface und verwendet dessen ToString(string format, IFormatProvider formatProvider) Methode?


Kha - Do 20.05.10 13:31

Da DateTime kein FrameworkElement ist, wird der ContentPresenter in Content letztlich darauf ToString aufrufen und das Ergebnis in einem TextBlock platzieren, aber da ist das Binding schon längst aus dem Spiel :) .


lord_fritte - Do 20.05.10 13:37

Ok verstehe, wieder was gelernt, also mit dem TextBlock geht es, Vielen Danke.