可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am trying to format a textblock which is bound to a TimeSpan
property. It works if the property is of type DateTime
but it fails if it is a TimeSpan
. I can get it done using a converter. But I am trying to find out if there is any alternatives.
Sample Code:
public TimeSpan MyTime { get; set; }
public Window2()
{
InitializeComponent();
MyTime = DateTime.Now.TimeOfDay;
DataContext = this;
}
Xaml
<TextBlock Text="{Binding MyTime,StringFormat=HH:mm}"/>
I am expecting the textblock to show only hours and mintes. But it is showing as:
19:10:46.8048860
回答1:
In .NET 3.5 you could use a MultiBinding instead
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}:{1}">
<Binding Path="MyTime.Hours"/>
<Binding Path="MyTime.Minutes"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Update
To answer the comments.
To make sure you output 2 digits even if hours or minutes is 0-9 you can use {0:00} instead of {0}. This will make sure the output for the time 12:01 is 12:01 instead of 12:1.
If you want to output 01:01 as 1:01 use StringFormat="{}{0}:{1:00}"
And Conditional formatting can be used to remove the negative sign for minutes. Instead of {1:00} we can use {1:00;00}
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0:00}:{1:00;00}">
<Binding Path="MyTime.Hours" />
<Binding Path="MyTime.Minutes" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
回答2:
The format string is intended to work on a DateTime
, not a TimeSpan
.
You could change your code to work with DateTime.Now
instead. Your xaml is fine:
<TextBlock Text="{Binding MyTime,StringFormat=HH:mm}"/>
Update
And from .Net 4 format a TimeSpan
as follows:
<TextBlock Text="{Binding MyTime,StringFormat=hh\\:mm}"/>
回答3:
Just to add to the pool, I'm successfully using this binding to display a TimeSpan in a production WPF app:
Binding="{Binding Time, Mode=TwoWay, StringFormat=\{0:h\\:mm\}}"
Took some tries to get the backslashes right :)
回答4:
StringFormat
must be in the form of a format string. In this case it would look like:
<TextBlock Text="{Binding MyTime,StringFormat=`Time values are {0:hh\\:mm}`}"/>
Note: if you want to display the total number of hours and minutes and the timespan happens to be greater than 24 hours, there's a caveat with your approach: Here's a workaround.
回答5:
For Multi bindings you need to pay attention since .NET 4.
A short overview below, tested with .NET 4.6:
Regular binding:
<TextBlock Text="{Binding Start, StringFormat='{}{0:hh\\:mm\\:ss}'}" />
Multi binding:
<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>
or you could use " instead of ' in the multibinding:
<MultiBinding StringFormat='{}{0:hh":"mm":"ss} -> {1:hh":"mm":"ss}'>
Note:
using StringFormat="{}{0:hh\:\:mm\:ss} -> {1:hh\:mm\:ss}" will not work on a MultiBinding, this will result in a blank result.
回答6:
WPF in .NET 4 now has timespan from strings http://msdn.microsoft.com/en-us/library/ee372286.aspx
I am using the following <TextBlock FontSize="12" Text="{Binding Path=TimeLeft, StringFormat={}{0:g}}" />
回答7:
I'm aware that this question is old now, but I'm surprised that no one suggested this simple StringFormat
which will work on a TimeSpan
directly:
<TextBlock Text="{Binding MyTime, StringFormat={}{0:hh}:{0:mm}, FallbackValue=00:00}"/>
回答8:
If you want to use StringFormat in a Label that uses the Content property, you can use ContentStringFormat to format your timespan:
<Label Content={Binding MyTimespan}" ContentStringFormat="{}{0:hh}:{0:mm}:{0:ss}"