source

XAML에서의 TimeSpan 포맷 방법

itover 2023. 4. 22. 09:21
반응형

XAML에서의 TimeSpan 포맷 방법

텍스트 블록의 포맷을 시도하고 있는 텍스트 블록은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}"/>

갱신하다

그리고 에서.넷4 포맷aTimeSpan다음과 같습니다.

<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>

갱신하다
댓글에 답하기 위해서.

시간 또는 분수가 0-9인 경우에도 두 자리를 출력하려면 {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>

풀에 추가하기 위해 이 바인딩을 사용하여 프로덕션 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시간보다 큰 시간 간격이 발생할 경우 다음과 같은 주의사항이 있습니다.여기 회피책이 있습니다.

다중 바인딩의 경우 이후 유의해야 합니다.넷 4

로 테스트한 간단한 개요는 다음과 같습니다.넷 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}"/>

의 WPF현재 NET 4에는 문자열 http://msdn.microsoft.com/en-us/library/ee372286.aspx부터의 타임 스팬이 있습니다.

는 다음과 것을 .<TextBlock FontSize="12" Text="{Binding Path=TimeLeft, StringFormat={}{0:g}}" />

시간 범위 문자열 형식(밀리초):

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

Mi 솔루션은 다음과 같습니다.

(필요한 횟수만큼 요소 0을 선택)

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

여기에는 StringFormat 옵션이 몇 가지 있습니다.단, 클린 XAML 스타일을 유지하면서 TimeSpan을 문자열 변환에 완전히 자유롭게 사용할 수 있도록 하려면 간단한 IValueConverter를 작성하는 옵션도 있습니다.

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
    }
}

그러면 예를 들어 Static Resource를 사용자 컨트롤에 포함할 수 있습니다.

<UserControl.Resources>
    <local:TimespanToSpecialStringConverter x:Key="TimespanToSpecialStringConverter" />
</UserControl.Resources>

마지막으로 일반적인 데이터 바인딩 내에서 TimespanToSpecialStringConverter를 적용합니다.

<TextBlock Text="{Binding Path=ATimespanDependencyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource TimespanToSpecialStringConverter}}" />

이것으로, XAML 를 클린 하면서, 필요에 따라서 스트링 변환을 프로그램적으로 변경할 수 있습니다.이것은 완전한 유연성이 필요한 경우에 한해서입니다.

PS: 읽어보았습니다만, 이미 Converter를 사용하고 있었습니다.따라서 이 답변은 '다른' 대안이 가능한지에 대한 질문에는 100% 들어맞지 않습니다.하지만, 많은 사람들이 이것을 유용하게 여길 수 있기 때문에, 나는 그것이 여기에 남겨졌으면 좋겠다.

언급URL : https://stackoverflow.com/questions/4563081/how-to-format-timespan-in-xaml

반응형

'source' 카테고리의 다른 글

환경변수를 인쇄/반향하는 방법  (0) 2023.04.22
Excel VBA - 범위전치 페이스트 복사  (0) 2023.04.22
선택한 ListBox 항목의 배경색 변경  (0) 2023.04.22
ICommand MVVM 구현  (0) 2023.04.22
SQL - 보유와어디에  (0) 2023.04.22