首页 > 解决方案 > 在 Xaml (UWP) 中格式化 TimeSpan

问题描述

如何TimeSpan使用自定义格式格式化 XAML 中的 a?我想要小时和分钟。

根据官方文档,在 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 解析删除了反斜杠,从而将“h:mm”传递给转换器(我通过调试器进行了验证)。

它也不喜欢两个反斜杠,因为这会从生成的 .g.cs 文件中引发编译器错误,说“\:”是“无法识别的转义序列”。

没有任何编码反斜杠的变体起作用。我努力了:

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,UWP 不支持 MultiBinding。

标签: c#xamluwpstring-formattingtimespan

解决方案


因为我需要反斜杠。XAML 解析删除了反斜杠,从而将“h:mm”传递给转换器(我通过调试器进行了验证)。

是的,是正确的,ConverterParameter是对象而不是字符串,这可能会导致在 xaml 解析时删除反斜杠。我认为您可以StringFormat为您创建属性并在初始化时TimeSpanFormatConverter传递。FormatConverter

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>

推荐阅读