Xamarin.Forms Formatowanie ciągu

Czasami wygodne jest użycie powiązań danych w celu wyświetlenia reprezentacji ciągu obiektu lub wartości. Na przykład możesz użyć elementu , Label aby wyświetlić bieżącą wartość elementu Slider. W tym powiązaniu Slider danych element jest źródłem, a elementem docelowym jest Text właściwość Label.

Podczas wyświetlania ciągów w kodzie najbardziej wydajne narzędzie to metoda statyczna String.Format . Ciąg formatowania zawiera kody formatowania specyficzne dla różnych typów obiektów i można dołączyć inny tekst wraz z sformatowanymi wartościami. Aby uzyskać więcej informacji na temat formatowania ciągów, zobacz artykuł Typy formatowania w programie .NET.

Właściwość StringFormat

Ta funkcja jest przenoszona do powiązań danych: należy ustawić StringFormat właściwość (lub StringFormat właściwość BindingBinding rozszerzenia znaczników) na standardowy ciąg formatowania platformy .NET z jednym symbolem zastępczym:

<Slider x:Name="slider" />
<Label Text="{Binding Source={x:Reference slider},
                      Path=Value,
                      StringFormat='The slider value is {0:F2}'}" />

Zwróć uwagę, że ciąg formatowania jest rozdzielany znakami pojedynczego cudzysłowu (apostrofu), aby pomóc analizatorowi XAML uniknąć traktowania nawiasów klamrowych jako innego rozszerzenia znaczników XAML. W przeciwnym razie ten ciąg bez znaku pojedynczego cudzysłowu jest tym samym ciągiem, którego można użyć do wyświetlenia wartości zmiennoprzecinkowej w wywołaniu metody String.Format. Specyfikacja F2 formatowania powoduje wyświetlanie wartości z dwoma miejscami dziesiętnymi.

Właściwość StringFormat ma sens tylko wtedy, gdy właściwość docelowa ma typ string, a tryb powiązania to OneWay lub TwoWay. W przypadku powiązań dwukierunkowych parametr ma zastosowanie tylko do wartości przekazywanych StringFormat ze źródła do obiektu docelowego.

Jak zobaczysz w następnym artykule dotyczącym ścieżki powiązania, powiązania danych mogą stać się dość złożone i zawiłe. Podczas debugowania tych powiązań danych można dodać element Label do pliku XAML za pomocą elementu , StringFormat aby wyświetlić niektóre wyniki pośrednie. Nawet jeśli używasz go tylko do wyświetlania typu obiektu, może to być przydatne.

Strona Formatowanie ciągu ilustruje kilka zastosowań StringFormat właściwości:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:sys="clr-namespace:System;assembly=netstandard"
             x:Class="DataBindingDemos.StringFormattingPage"
             Title="String Formatting">

    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Label">
                <Setter Property="HorizontalTextAlignment" Value="Center" />
            </Style>

            <Style TargetType="BoxView">
                <Setter Property="Color" Value="Blue" />
                <Setter Property="HeightRequest" Value="2" />
                <Setter Property="Margin" Value="0, 5" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout Margin="10">
        <Slider x:Name="slider" />
        <Label Text="{Binding Source={x:Reference slider},
                              Path=Value,
                              StringFormat='The slider value is {0:F2}'}" />

        <BoxView />

        <TimePicker x:Name="timePicker" />
        <Label Text="{Binding Source={x:Reference timePicker},
                              Path=Time,
                              StringFormat='The TimeSpan is {0:c}'}" />

        <BoxView />

        <Entry x:Name="entry" />
        <Label Text="{Binding Source={x:Reference entry},
                              Path=Text,
                              StringFormat='The Entry text is &quot;{0}&quot;'}" />

        <BoxView />

        <StackLayout BindingContext="{x:Static sys:DateTime.Now}">
            <Label Text="{Binding}" />
            <Label Text="{Binding Path=Ticks,
                                  StringFormat='{0:N0} ticks since 1/1/1'}" />
            <Label Text="{Binding StringFormat='The {{0:MMMM}} specifier produces {0:MMMM}'}" />
            <Label Text="{Binding StringFormat='The long date is {0:D}'}" />
        </StackLayout>

        <BoxView />

        <StackLayout BindingContext="{x:Static sys:Math.PI}">
            <Label Text="{Binding}" />
            <Label Text="{Binding StringFormat='PI to 4 decimal points = {0:F4}'}" />
            <Label Text="{Binding StringFormat='PI in scientific notation = {0:E7}'}" />
        </StackLayout>
    </StackLayout>
</ContentPage>

Powiązania w obiekcie Slider i TimePicker pokazują użycie specyfikacji formatu określonych dla double typów danych i .TimeSpan Element StringFormat , który wyświetla tekst z Entry widoku, pokazuje, jak określić podwójne cudzysłów w ciągu formatowania przy użyciu &quot; jednostki HTML.

Następna sekcja w pliku XAML jest StackLayout elementem z ustawionym BindingContextx:Static rozszerzeniem znaczników odwołującym się do właściwości statycznej DateTime.Now . Pierwsze powiązanie nie ma właściwości:

<Label Text="{Binding}" />

Spowoduje to po prostu wyświetlenie DateTime wartości BindingContext z domyślnym formatowaniem. Drugie powiązanie wyświetla Ticks właściwość DateTime, podczas gdy pozostałe dwa powiązania wyświetlają DateTime się z określonym formatowaniem. Zwróć uwagę na to:StringFormat

<Label Text="{Binding StringFormat='The {{0:MMMM}} specifier produces {0:MMMM}'}" />

Jeśli musisz wyświetlić nawiasy klamrowe w lewym lub prawym nawiasie klamrowym w ciągu formatowania, po prostu użyj pary z nich.

Ostatnia sekcja ustawia BindingContext wartość na wartość Math.PI i wyświetla ją z domyślnym formatowaniem i dwoma różnymi typami formatowania liczbowego.

Oto uruchomiony program:

Formatowanie ciągu

Modely widoków i formatowanie ciągów

Jeśli używasz Label elementu i StringFormat wyświetlasz wartość widoku, który jest również obiektem docelowym modelu ViewModel, możesz zdefiniować powiązanie z widoku do Label elementu lub z modelu ViewModel do elementu Label. Ogólnie rzecz biorąc, drugie podejście jest najlepsze, ponieważ sprawdza, czy powiązania między modelem View i ViewModel działają.

To podejście jest pokazane w przykładzie Better Color Selector , który używa tego samego modelu ViewModel co program selektora kolorów prostych pokazany w artykule Tryb powiązania:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataBindingDemos"
             x:Class="DataBindingDemos.BetterColorSelectorPage"
             Title="Better Color Selector">

    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Slider">
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
            </Style>

            <Style TargetType="Label">
                <Setter Property="HorizontalTextAlignment" Value="Center" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout>
        <StackLayout.BindingContext>
            <local:HslColorViewModel Color="Sienna" />
        </StackLayout.BindingContext>

        <BoxView Color="{Binding Color}"
                 VerticalOptions="FillAndExpand" />

        <StackLayout Margin="10, 0">
            <Label Text="{Binding Name}" />

            <Slider Value="{Binding Hue}" />
            <Label Text="{Binding Hue, StringFormat='Hue = {0:F2}'}" />

            <Slider Value="{Binding Saturation}" />
            <Label Text="{Binding Saturation, StringFormat='Saturation = {0:F2}'}" />

            <Slider Value="{Binding Luminosity}" />
            <Label Text="{Binding Luminosity, StringFormat='Luminosity = {0:F2}'}" />
        </StackLayout>
    </StackLayout>
</ContentPage>    

Istnieją teraz trzy pary Slider elementów i Label , które są powiązane z tą samą właściwością źródłową HslColorViewModel w obiekcie. Jedyną różnicą StringFormat jest to, że Label ma właściwość do wyświetlenia każdej Slider wartości.

Selektor kolorów lepszej

Być może zastanawiasz się, jak można wyświetlić wartości RGB (czerwony, zielony, niebieski) w tradycyjnym formacie szesnastkowym dwucyfrowym. Te wartości całkowite nie są bezpośrednio dostępne w Color strukturze. Jednym z rozwiązań byłoby obliczenie wartości całkowitych składników kolorów w modelu ViewModel i uwidocznienie ich jako właściwości. Następnie można je sformatować przy X2 użyciu specyfikacji formatowania.

Inne podejście jest bardziej ogólne: Można napisać konwerter wartości powiązania, jak opisano w dalszej części artykułu, Binding Value Converters (Konwertery powiązań wartości).

W następnym artykule opisano jednak bardziej szczegółowo ścieżkę powiązania i pokazano, jak można jej używać do odwołowania się do właściwości podrzędnych i elementów w kolekcjach.