Формат TimeSpan в Xaml (UWP) - PullRequest
0 голосов
/ 08 июня 2019

Как отформатировать TimeSpan в XAML с пользовательским форматом? Я хочу час и минуты.

На основании официальной документации способ сделать это в C # выглядит следующим образом:

interval.ToString(@"h\:mm");

Я хочу иметь возможность отформатировать TimeSpan в XAML, однако, из привязки. Это решение кажется жизнеспособным, но я хотел создать общий конвертер, в который я мог бы передать строку формата. Мой конвертер выглядит следующим образом:

public class TimeSpanFormatConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        string result = "";
        if (value == null)
        {
            return null;
        }

        if (parameter == null)
        {
            return value;
        }

        if (value is TimeSpan timeSpan)
        {
            try
            {
                result = timeSpan.ToString((string)parameter);
            }
            catch (Exception e)
            {
                result = "";
            }
        }

        return result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

Теоретически я мог бы использовать этот преобразователь следующим образом:

<Page.Resources>
    <converters:TimeSpanFormatConverter x:key="TimeSpanConverter"></converters:TimeSpanFormatConverter>
</Page.Resources>

<Grid>
    <!-- Some properties omitted for brevity. -->
    <ListView>
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="models:MyModel">
                <Grid>

                    <!-- PROBLEM IS HERE -->
                    <TextBlock Text="{x:Bind Interval, Converter={StaticResource TimeSpanConverter}, ConverterParameter='h\:mm'}"></TextBlock>

                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

Обратите внимание, что в MyModel есть свойство с именем Interval типа TimeSpan.

Однако это не работает, потому что мне нужен обратный слеш. Синтаксический анализ XAML удаляет обратную косую черту, передавая преобразователю «ч: мм» (что я проверял через отладчик).

Ему также не нравятся две обратные косые черты, так как это приводит к ошибке компилятора из сгенерированного файла .g.cs, говоря, что «\:» является «нераспознанной escape-последовательностью».

Варианты кодирования обратной косой черты не работали. Я пробовал:

h:mm
h\:mm
h\\:mm
h\\\:mm
h&#92;:mm
h&#92;\:mm
h&#92;&#92;:mm
h&#92;&#92;&#58;mm

Какая волшебная цепочка букв должна быть помещена в ConverterParameter?

В качестве альтернативы решение MultiBinding объяснило здесь выглядело многообещающе, но, согласно Visual Studio, MultiBinding не поддерживается в UWP.

1 Ответ

0 голосов
/ 10 июня 2019

потому что мне нужен обратный слеш.Синтаксический анализ XAML удаляет обратную косую черту, передавая преобразователю «ч: мм» (что я проверял через отладчик).

Да, правильно, ConverterParameter является объектом, но неstring, это может привести к удалению обратной косой черты при синтаксическом анализе xaml.Я думаю, что вы можете создать StringFormat свойство для вашего TimeSpanFormatConverter и передать Format при Converter инициализации.

public class TimeSpanFormatConverter : IValueConverter
{
    public string StringFormat { get; set; }
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        string result = "";
        if (value == null)
        {
            return null;
        }

        if (parameter == null)
        {
            return value;
        }

        if (value is TimeSpan timeSpan)
        {
            try
            {
                result = timeSpan.ToString(StringFormat);
            }
            catch (Exception e)
            {
                result = "";
            }
        }

        return result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

Использование

<Page.Resources>
    <local:TimeSpanFormatConverter x:Key="TimeSpanConverter" StringFormat="h\:mm"/>
</Page.Resources>
<Grid>
    <TextBlock VerticalAlignment="Center" Text="{x:Bind Interval, Converter={StaticResource TimeSpanConverter},Mode=TwoWay}"></TextBlock>
</Grid>
...