XAMLでTimeSpanをフォーマットする方法


92

TimeSpanプロパティにバインドされているテキストブロックをフォーマットしようとしています。プロパティがtypeの場合は機能しますが、の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


2010年に遡って実行していた.Netのバージョンを覚えていますか?Windows Phone XAMLで同様の問題が発生しています: stackoverflow.com/q/18679365/1001985
McGarnagle

注:すべての形式の先頭の{}はエスケープシーケンスであり、形式指定子ではありません。これにより、XAMLは、バックスラッシュを必要とせずに、形式内でさらにブラケットを許容します。
Grault、2014

回答:


88

.NET 3.5では、代わりにMultiBindingを使用できます

<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="{}{0}:{1}">
            <Binding Path="MyTime.Hours"/>
            <Binding Path="MyTime.Minutes"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

更新
コメントに答える。

時間または分が0〜9であっても確実に2桁を出力するには、{0}の代わりに{0:00}を使用できます。これにより、時間12:01の出力は12:1ではなく12:01になります。
01:01を1:01として出力する場合StringFormat="{}{0}:{1:00}"

また、条件付き書式を使用して、分のマイナス記号を削除できます。{1:00}の代わりに{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>

@chibacity:ありがとう!私はすでにあなたの答えを信用しているので、二度とそれを行うことはできません:)しかし、私は質問をお気に入りに入れました。とても良い
Fredrik Hedblad

1
分の部分に1桁しかない場合、この出力は「10:1」または「4:9」ではありませんか?
Cygon

@Cygon:これを修正する方法については、私の最新の回答を参照してください。{0}の代わりに{0:D2}を使用
Fredrik Hedblad

これは、7時間12分の負のTimedurationに対して「-07:-12」を出力します。期間がマイナス7時間の場合、出力は「-07:00」になります。しかし、負の期間にゼロ以外の分があるとすぐに、マイナスが追加さ.Hoursれます.Minutes
tzippy

@FredrikHedblad 分単位ではTotalMinutesなく表示したいMinutes(1時間よりも長いタイムスパンを表示するため)。しかし、TotalMinutesプロパティはダブルフォーマットであるため、バインドを使用し<Binding Path="MyTime.TotalMinutes" />て丸められた出力が生成されます。これは悪いことです。丸めの代わりに切り捨てられた値を表示する必要があります。doubleをintに切り捨てるためのカスタム値コンバーターを使用せずにそれを達成することは可能ですか?
ドミニクパロ2016年

139

フォーマット文字列は、DateTimeではなくで機能することを目的としていますTimeSpan

DateTime.Now代わりに動作するようにコードを変更できます。あなたのxamlは大丈夫です:

<TextBlock Text="{Binding MyTime,StringFormat=HH:mm}"/>

更新

そして.Net 4フォーマットからTimeSpan次のように:

<TextBlock Text="{Binding MyTime,StringFormat=hh\\:mm}"/>

はい...しかし、タイムスパン値をフォーマットできる方法を探しています。
biju

1
私は、日付のコレクションから私の時間の一部をフィルタリング明確な取って、私のロジックが行く道をsorting..blah..itsています
biju

@biju TimeSpanのフォーマット文字列でサンプルを更新しました。
Tim Lloyd

2
私は何か間違っているのかわかりませんが、ここではまだ機能しません。VisualStudio2008、Framework 3.5
biju

1
これは正解であり、上記のマークではありません。dot net 3.5の場合でも、推奨される回答の代わりにコンバーターを使用します。
MikeKulls 2012年

44

単にプールに追加するために、私はこのバインディングを正常に使用して、本番WPFアプリでTimeSpanを表示しています。

Binding="{Binding Time, Mode=TwoWay, StringFormat=\{0:h\\:mm\}}"

バックスラッシュを正しくするためにいくつかの試みをしました:)


5
秒の端数に行きたい場合は、カンマもエスケープする必要があります:{0:hh \\:mm \\:ss \\。ffff}
Rashack

StringFormat = \ {0:hh \\:mm \\:ss \\。fff \}
Stepan Ivanenko

いつもの大きな間違いは、DateTime形式の文字列のようにHを使用していたことです。しかし、明らかにTimeSpanには12/24フォーマットはありません...
M Stoerzel

22

StringFormat書式文字列の形式でなければなりません。この場合は次のようになります。

<TextBlock Text="{Binding MyTime,StringFormat=`Time values are {0:hh\\:mm}`}"/>

注:時間と分の合計数を表示する必要があり、タイムスパンがたまたま24時間を超えている場合は、アプローチに注意が必要です。回避策は次のとおりです。


@biju-更新された構文。StringFormat値の前後に単一引用符がありませんでした。
Peter Lillevold、2010

:はい、@chibacityサンプルが示すように、二重の\はエスケープする必要が
ピーターLillevold

1
実際、これは.Net 4.0でのみ機能します。書式設定文字列は、.Net 3.5では完全に無視されます。
Peter Lillevold、2010

2
また、これはTextBlockでは機能しますが、Labelでは機能しません(!)。
シャックル

2
@Shackles StringFormatは、BindingのターゲットがString型のプロパティである場合にのみ使用されます。Label.ContentはObjectであるため、無視されます。TextBlock.Textは文字列なので、使用されます。
15ee8f99-57ff-4f92-890c-b56153 2016年

16

マルチバインディングについては、.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の上に仕事、これは空白の結果をもたらすであろう。


13

私はこの質問が古いことを知っていますが、誰もがこの単純な方法StringFormatTimeSpan直接動作することを示唆していないことに驚いています:

<TextBlock Text="{Binding MyTime, StringFormat={}{0:hh}:{0:mm}, FallbackValue=00:00}"/>

2
これに関する混乱がたくさんあります。おそらく.NET 4で構文が変更されたようです
McGarnagle


8

Contentプロパティを使用するLabelでStringFormatを使用する場合は、ContentStringFormatを使用してタイムスパンをフォーマットできます。

<Label Content={Binding MyTimespan}" ContentStringFormat="{}{0:hh}:{0:mm}:{0:ss}"

回答で述べることは二重強調に値します。Contentプロパティを使用するXAMLコントロール(つまり、Textプロパティをとして使用しないなどTextBlock)では、プロパティを使用するContentStringFormat 必要あります。StringFormatバインディングの一部として指定しても機能しません。
Informagic

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.