我正在尝试格式化绑定到
TimeSpan
属性的文本块。如果属性是 DateTime
类型,则有效,但如果是 TimeSpan
类型,则失败。我可以使用转换器来完成它。但我正在尝试找出是否有其他选择。
示例代码:
public TimeSpan MyTime { get; set; }
public Window2()
{
InitializeComponent();
MyTime = DateTime.Now.TimeOfDay;
DataContext = this;
}
Xaml
<TextBlock Text="{Binding MyTime,StringFormat=HH:mm}"/>
我希望文本块仅显示小时和分钟。但它显示为:
19:10:46.8048860
格式字符串适用于
DateTime
,而不是 TimeSpan
。
您可以更改代码以使用
DateTime.Now
来代替。你的xaml没问题:
<TextBlock Text="{Binding MyTime,StringFormat=HH:mm}"/>
更新
并从 .Net 4 格式化
TimeSpan
,如下所示:
<TextBlock Text="{Binding MyTime,StringFormat=hh\\:mm}"/>
在 .NET 3.5 中,您可以使用 MultiBinding 来代替
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}:{1}">
<Binding Path="MyTime.Hours"/>
<Binding Path="MyTime.Minutes"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
更新
回复评论。
为了确保输出 2 位数字,即使小时或分钟是 0-9,您也可以使用 {0:00} 而不是 {0}。这将确保时间 12:01 的输出是 12:01 而不是 12:1。
如果要将 01:01 输出为 1:01,请使用
StringFormat="{}{0}:{1:00}"
和条件格式可用于删除几分钟的负号。我们可以使用 {1:00;00} 代替 {1:00}
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0:00}:{1:00;00}">
<Binding Path="MyTime.Hours" />
<Binding Path="MyTime.Minutes" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
为了添加到池中,我成功地使用此绑定在生产 WPF 应用程序中显示 TimeSpan:
Binding="{Binding Time, Mode=TwoWay, StringFormat=\{0:h\\:mm\}}"
做了一些尝试才使反斜杠正确:)
如果您想在使用 Content 属性的标签中使用 StringFormat,您可以使用 ContentStringFormat 来格式化您的时间跨度:
<Label Content={Binding MyTimespan}" ContentStringFormat="{}{0:hh}:{0:mm}:{0:ss}"
StringFormat
必须采用格式字符串的形式。在这种情况下,它看起来像:
<TextBlock Text="{Binding MyTime,StringFormat=`Time values are {0:hh\\:mm}`}"/>
注意:如果您想显示总小时数和分钟数,并且时间跨度恰好大于 24 小时,则您的方法有一个警告:这里有一个解决方法。
从 .NET 4 开始,对于多重绑定需要注意。
下面是使用 .NET 4.6 进行测试的简短概述:
常规装订:
<TextBlock Text="{Binding Start, StringFormat='{}{0:hh\\:mm\\:ss}'}" />
多重绑定:
<TextBlock.Text>
<MultiBinding StringFormat="{}{0:hh':'mm':'ss} -> {1:hh':'mm':'ss}">
<Binding Path="Start" Mode="OneWay" UpdateSourceTrigger="PropertyChanged" />
<Binding Path="End" Mode="OneWay" UpdateSourceTrigger="PropertyChanged" />
</MultiBinding>
</TextBlock.Text>
或者您可以在多重绑定中使用 " 代替 ':
<MultiBinding StringFormat='{}{0:hh":"mm":"ss} -> {1:hh":"mm":"ss}'>
注意: 使用 StringFormat="{}{0:hh\:\:mm\:ss} -> {1:hh\:mm\:ss}" 将不适用于 MultiBinding,这将导致空白结果。
StringFormat
,它可以直接在
TimeSpan
上工作:
<TextBlock Text="{Binding MyTime, StringFormat={}{0:hh}:{0:mm}, FallbackValue=00:00}"/>
<TextBlock Text="{Binding MyTime, StringFormat=\{0:hh\\:mm\\:ss\\.fff\}}"/>
(根据需要多次复制元素 0)
<TextBlock Text="{Binding MyTime, StringFormat='{0:hh}:{0:mm}'}"/>
using System;
using System.Windows.Data;
namespace Bla
{
[System.Windows.Data.ValueConversion(typeof(TimeSpan), typeof(string))]
public class TimespanToSpecialStringConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (targetType != typeof(string))
throw new InvalidOperationException("The target must be a string");
var timeSpan = (TimeSpan)value;
string minutes = timeSpan.Minutes < 10 ? "0" + timeSpan.Minutes : ""+timeSpan.Minutes;
string seconds = timeSpan.Seconds < 10 ? "0" + timeSpan.Seconds : "" + timeSpan.Seconds;
return "" + timeSpan.TotalHours + ":" + minutes + ":" + seconds;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (targetType != typeof(TimeSpan))
throw new InvalidOperationException("The target must be a TimeSpan");
return TimeSpan.Zero;
}
#endregion
}
}
那么,例如,用户控件中可以有一个 StaticResource :
<UserControl.Resources>
<local:TimespanToSpecialStringConverter x:Key="TimespanToSpecialStringConverter" />
</UserControl.Resources>
最后在典型的数据绑定中应用 TimespanToSpecialStringConverter :
<TextBlock Text="{Binding Path=ATimespanDependencyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource TimespanToSpecialStringConverter}}" />
现在,您可以根据需要以编程方式更改字符串转换,同时拥有干净的 XAML :) 请记住,如果您需要完全的灵活性,这只是另一个选择。PS:现在我了解到,您已经在使用转换器了。因此,这个答案并不 100% 适合关于什么是可能的“其他”替代方案的问题。然而,我希望它留在这里,因为很多人可能会发现这是一个有用的方法。
<Label Content="{Binding TimeOff}" ContentStringFormat="{}{0:%d}:{0:%h}:{0:%m}:{0:%s}" />
不幸的是,ContentStringFormat 在 TextBlocks 中不可用...