XAML에서 TimeSpan을 포맷하는 방법


92

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


2010 년에 실행 중이던 .Net 버전을 기억하십니까? Windows Phone XAML에서 비슷한 문제가 있습니다. stackoverflow.com/q/18679365/1001985
McGarnagle 2013

참고 : 모든 형식의 시작 부분에있는 {}는 형식 지정자가 아니라 이스케이프 시퀀스입니다. 이로 인해 XAML은 백 슬래시없이 형식에서 추가 대괄호를 허용합니다.
Grault

답변:


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 2010

1
분 부분에 숫자가 하나만 있으면이 출력이 "10 : 1"또는 "4 : 9"가 아닐까요?
Cygon 2011

@Cygon :이 문제를 해결하는 방법은 업데이트 된 답변을 참조하십시오. 사용 {0 : D2} 대신 {0}
프레드릭 Hedblad

7 시간 12 분의 음수 Timeduration에 대해 "-07 : -12"를 출력합니다. 기간이 마이너스 7 시간이면 출력은 "-07 : 00"이됩니다. 그러나 음수 기간에 0이 아닌 분이있는 즉시 마이너스가 추가 .Hours됩니다..Minutes
tzippy

@FredrikHedblad 분 부분 TotalMinutes대신 표시하고 싶습니다 Minutes(1 시간 동안 가장 긴 시간을 표시하기 위해). 그러나 TotalMinutes속성은 이중 형식이므로을 사용하여 바인딩 <Binding Path="MyTime.TotalMinutes" />하면 반올림 된 출력 이 생성됩니다. 이는 좋지 않습니다. 반올림 대신 잘린 값을 표시해야합니다. double을 int로 자르기 위해 사용자 정의 값 변환기를 사용하지 않고도 달성 할 수 있습니까?
Dominik Palo

139

형식 문자열은 작업 할 의도 DateTime가 아닌를 TimeSpan.

DateTime.Now대신 사용할 코드를 변경할 수 있습니다 . 귀하의 xaml은 괜찮습니다.

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

최신 정보

그리고 다음과 같이 .Net 4 형식 a TimeSpan에서 :

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

예 ...하지만 Timespan 값을 형식화 할 수있는 방법을 찾고 있습니다.
biju 2010

1
나는 날짜 모음에서 내 시간 부분을 필터링하고, 구별하고, 정렬합니다. .blah .. 내 논리가 진행되는 방식
biju

@biju TimeSpan의 형식 문자열로 샘플을 업데이트했습니다.
Tim Lloyd

2
내가 뭘 잘못하고 있는지 모르겠지만 여기서는 여전히 작동하지 않습니다 .VisualStudio 2008, 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

그리고 예, @chibacity 샘플에서 볼 수 있듯이 다음을 탈출하려면 이중 \가 필요합니다.
Peter Lillevold dec

1
그리고 실제로 이것은 .Net 4.0에서만 작동합니다! .Net 3.5에서는 형식 문자열이 완전히 무시됩니다.
Peter Lillevold

2
또한 이것은 TextBlock에서는 작동하지만 Label에서는 작동하지 않습니다 (!).
Shackles

2
@Shackles StringFormat은 Binding의 대상이 String 유형의 속성 인 경우에만 사용됩니다. Label.Content는 Object이므로 무시됩니다. TextBlock.Text는 문자열이므로 사용됩니다.
15ee8f99-57ff-4f92-890c-b56153

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을 "{HH \ : \ mm \ 0 SS를} {} -> {1 : HH : \ mm \ SS}"수 없습니다 MultiBinding에 작업이 빈 결과가 발생합니다.


13

나는이 질문이 이제 오래되었다는 것을 알고 있지만 아무도 직접적으로 StringFormat작동 할 간단한 제안을 제안하지 않았다는 것에 놀랐습니다 TimeSpan.

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

2
이것에 대한 많은 혼란. .NET 4에서 구문이 변경된 것 같습니다.
McGarnagle 2013

12

.NET 4의 WPF에는 이제 문자열 http://msdn.microsoft.com/en-us/library/ee372286.aspx의 시간 범위가 있습니다 .

나는 다음을 사용하고있다 <TextBlock FontSize="12" Text="{Binding Path=TimeLeft, StringFormat={}{0:g}}" />


1
실제로 .NET 4-4.5에서 작동합니다. 이 스레드의 다른 솔루션은 없습니다.
erodewald

2012 년 2 월에 그랬을 수도 있지만 더 이상 그렇지 않습니다.
Sheridan

8

Content 속성을 사용하는 Label에서 StringFormat을 사용하려는 경우 ContentStringFormat 을 사용하여 시간 범위를 형식화 할 수 있습니다 .

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

답변에 언급 한 내용은 이중 강조 표시가 필요합니다. Content속성 을 사용하는 XAML 컨트롤 (예 : Texta TextBlock와 같은 속성 이 아님)에서는 속성을 ContentStringFormat 사용해야 합니다. StringFormat바인딩의 일부로 지정 하면 작동하지 않습니다.
Informagic

2

밀리 초가있는 TimeSpan StringFormat :

<TextBlock Text="{Binding MyTime, StringFormat=\{0:hh\\:mm\\:ss\\.fff\}}"/>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.