Tworząc aplikacje często spotykamy się z przypadkiem, kiedy chcemy stworzyć listę obiektów pobieranych z bazy danych. W WPF, korzystając z XAMLa możemy to zrobić poprzez mechanizm Data Binding (Data Binding Overview na MSDN ).

Co jeśli interesuje nas lista wieloelementowa, ładnie sformatowana pod względem ustawienia elementów i formatu liczb? Do tego celu możemy użyć Data Binding + Grid + StringFormat.

Korzystamy z bazy danych opisanej w artykule Baza Danych w Windows Phone 7 .

Podłączenie danych

W pliku MainPage.xaml.cs podłączamy bazę danych do kontekstu strony:

public MainPage()
{
    InitializeComponent();
    this.DataContext = App.ViewModel;
}

W ten sposób cała strona ma kontekst danych, z którego może pobierać, usuwać itp. dane.

Szablon elementu listy

Najważniejsza część — w MainPage.xaml tworzymy szablon każdego wiersza w PhoneApplicationPage.Resources:

<phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Key="EntriesListBoxItemTemplate">
        <Border Background="{StaticResource TransparentBrush}" Padding="20">
            <Grid HorizontalAlignment="Stretch"
                  Background="{StaticResource TransparentBrush}">

                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="80" />
                    <ColumnDefinition Width="80" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <Grid.RowDefinitions>
                    <RowDefinition Height="60" />
                    <RowDefinition Height="60" />
                </Grid.RowDefinitions>

                <Grid Grid.Column="0" Grid.ColumnSpan="1"
                      Grid.Row="0" Grid.RowSpan="2"
                      Background="{StaticResource PhoneAccentBrush}"
                      Width="110" Height="110">
                    <TextBlock
                        Text="{Binding ItemFuelMill, StringFormat=\{0:0.00\}}"
                        Foreground="White"
                        FontSize="{StaticResource PhoneFontSizeExtraLarge}"
                        VerticalAlignment="Center"
                        HorizontalAlignment="Right" />
                </Grid>

                <TextBlock
                    Text="{Binding ItemDate, StringFormat=\{0: MMMM d\, yyyy\}}"
                    FontSize="{StaticResource PhoneFontSizeLarge}"
                    Grid.Column="1" Grid.ColumnSpan="4"
                    Grid.Row="0" Grid.RowSpan="1"
                    VerticalAlignment="Top" Margin="0, 12, 0, 0" />

                <TextBlock
                    Text="{Binding ItemDist, StringFormat=\{0:0.0\}km}"
                    FontSize="{StaticResource PhoneFontSizeSmall}"
                    Grid.Column="1" Grid.ColumnSpan="1"
                    Grid.Row="1" Grid.RowSpan="1"
                    VerticalAlignment="Top" HorizontalAlignment="Right" />

                <TextBlock
                    Text="{Binding ItemRefuel, StringFormat=\{0:0.0\}l}"
                    FontSize="{StaticResource PhoneFontSizeSmall}"
                    Grid.Column="2" Grid.ColumnSpan="1"
                    Grid.Row="1" Grid.RowSpan="1"
                    VerticalAlignment="Top" HorizontalAlignment="Right" />

                <TextBlock
                    Text="{Binding ItemFPrice, StringFormat=\{0:0.0\}PLN}"
                    FontSize="{StaticResource PhoneFontSizeSmall}"
                    Grid.Column="3" Grid.ColumnSpan="1"
                    Grid.Row="1" Grid.RowSpan="1"
                    VerticalAlignment="Top" HorizontalAlignment="Right" />

            </Grid>
        </Border>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

Jak działa StringFormat w Bindingu

Cała magia odbywa się tutaj:

Text="{Binding ItemRefuel, StringFormat=\{0:0.0\}l}"

Oznacza to: weź z wiersza wartość elementu ItemRefuel i nadaj mu format {0:0.0}l — jeśli wartość to 7.53, kontrolka wyświetli 7.5l.

Bardzo ważne są escape characters (\{ i \}), które mówią mechanizmowi, że nawiasy nie należą do Bindingu, lecz do StringFormat.

Operacja ta ma na celu tylko wyświetlać dane, nie modyfikować. Działa tryb OneWay — “tylko pobieraj, nie wysyłaj do bazy”.

Dla trybu TwoWay istnieje alternatywa — stworzenie własnego konwertera implementującego interfejs IValueConverter z metodami Convert i ConvertBack.

Więcej: Data Binding and StringFormat in Silverlight – Matt Duffield