XAML'de TimeSpan nasıl biçimlendirilir


94

Bir özelliğe bağlı bir metin bloğunu biçimlendirmeye çalışıyorum TimeSpan. Özellik türündeyse çalışır, DateTimeancak bir TimeSpan. Bunu bir dönüştürücü kullanarak yapabilirim. Ama herhangi bir alternatif olup olmadığını bulmaya çalışıyorum.

Basit kod:

public TimeSpan MyTime { get; set; }

public Window2()
{
    InitializeComponent();
    MyTime = DateTime.Now.TimeOfDay;
    DataContext = this;
}

Xaml

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

Metin bloğunun yalnızca saatleri ve darphaneleri göstermesini bekliyorum. Ancak şu şekilde görünüyor:

19: 10: 46.8048860


2010'da .Net'in hangi sürümünü çalıştırdığınızı hatırlıyor musunuz? Windows Phone XAML ile benzer bir sorun yaşıyorum: stackoverflow.com/q/18679365/1001985
McGarnagle

Not: Tüm biçimlerin başındaki {}, bir biçim belirleyicisi değil, bir çıkış dizisidir. XAML'in ters eğik çizgi gerektirmeden biçimdeki diğer parantezleri tolere etmesine neden olur.
Grault

Yanıtlar:


90

.NET 3.5'te bunun yerine bir MultiBinding kullanabilirsiniz

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

Güncelle
Yorumlara cevap vermek için.

Saat veya dakika 0-9 olsa bile 2 basamak çıktı aldığınızdan emin olmak için {0} yerine {0:00} kullanabilirsiniz. Bu, 12:01 için çıktının 12: 1 yerine 12:01 olmasını sağlayacaktır.
01:01 çıkışını 1:01 olarak yapmak istiyorsanızStringFormat="{}{0}:{1:00}"

Ve Koşullu biçimlendirme dakika eksi işareti kaldırmak için kullanılabilir. {1:00} yerine {1: 00; 00} kullanabiliriz

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

@chibacity: Teşekkürler! Cevabınızı zaten kredilendirdim, bu yüzden tekrar yapamam :) Ama soruyu favorilere ekledim, böylece ihtiyacım olursa çözümünüzü bulabilirim! Çok güzel
Fredrik Hedblad

1
Dakika bölümünde sadece bir rakam varsa, bu "10: 1" veya "4: 9" çıktısı vermez mi?
Cygon

@Cygon: Bunu nasıl düzelteceğime dair güncellenmiş cevabıma bakın. {0} yerine {0: D2} kullanın
Fredrik Hedblad

Bu, 7 saat 12 dakikalık negatif Zamanlama için "-07: -12" sonucunu verir. süre eksi 7 saatse çıktı "-07: 00" olur. Ancak negatif sürede sıfırdan farklı bir dakika gelir gelmez, eksi .Hours.Minutes
41'e

@FredrikHedblad Dakika kısmı TotalMinutesyerine göstermek istiyorum Minutes(1 saatten daha uzun zaman aralıklarını göstermek için). Ancak TotalMinutesözellik çift biçimdedir, bu nedenle <Binding Path="MyTime.TotalMinutes" />yuvarlatılmış çıktıyı kullanarak bağlama yapmak kötüdür - yuvarlanmış yerine kesilmiş değeri göstermem gerekir. Double to int'i kesmek için özel bir değer dönüştürücü kullanmadan elde etmek mümkün mü?
Dominik Palo

144

Biçim dizesinin a üzerinde DateTimedeğil , a üzerinde çalışması amaçlanmıştır TimeSpan.

Kodunuzu DateTime.Nowbunun yerine çalışacak şekilde değiştirebilirsiniz . Xaml'iniz iyi:

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

Güncelleme

Ve .Net 4 formatından a TimeSpanaşağıdaki gibidir:

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

Evet ... Ama bir Timespan değerini biçimlendirmenin bir yolunu arıyorum.
biju

1
Zaman bölümümü bir tarih koleksiyonundan filtreliyorum, farklı alarak, sıralıyorum..blah..bunu mantığımın gidişatı gibi
biju

@biju Örneği TimeSpan için bir biçim dizesiyle güncelledim.
Tim Lloyd

2
Yanlış bir şey yapıp yapmadığımı bilmiyorum ... ama hala benim için çalışmıyor.VisualStudio 2008, Framework 3.5
biju

1
Bu doğru cevaptır, yukarıda belirtilen cevap değil. Nokta net 3.5 için bile önerilen yanıt yerine bir dönüştürücü kullanın.
MikeKulls

44

Yalnızca havuza eklemek için, bir üretim WPF uygulamasında bir TimeSpan görüntülemek için bu bağlamayı başarıyla kullanıyorum:

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

Ters eğik çizgileri düzeltmek için bazı denemeler yapıldı :)


5
Saniyenin kesirlerine gitmek isterseniz virgülden de kaçmanız gerekir: {0: hh \\: mm \\: ss \\.
Ffff

StringFormat = \ {0: hh \\: mm \\: ss \\. Fff \}
Stepan Ivanenko

Her zaman en büyük hatam, DateTime format dizgisi gibi H kullanmamdı. Ama belli ki TimeSpan için 12/24 formatı yok ...
M Stoerzel

21

StringFormatbiçim dizesi biçiminde olmalıdır. Bu durumda şöyle görünür:

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

Not: Toplam saat ve dakika sayısını görüntülemek istiyorsanız ve zaman aralığı 24 saatten fazla olursa, yaklaşımınızla ilgili bir uyarı var: İşte bir geçici çözüm .


@biju - güncellenmiş sözdizimi. StringFormat değeri etrafında tek tırnak işaretleri eksikti.
Peter Lillevold

Ve evet, @chibacity örneğinin gösterdiği gibi, şunlardan kaçmak için çift \ gereklidir:
Peter Lillevold

1
ve aslında, bu yalnızca .Net 4.0'da çalışır! Biçim dizesi .Net 3.5'te tamamen yok sayılır.
Peter Lillevold

2
Ayrıca, bunun bir TextBlock ile çalıştığını, ancak bir Etiketle (!) Çalışmadığını unutmayın.
Shackles

2
@Shackles StringFormat yalnızca Binding'in hedefi String türünde bir özellikse kullanılır. Label.Content Nesne olduğundan yok sayılır. TextBlock.Text bir dizedir, bu yüzden kullanılır.
15ee8f99-57ff-4f92-890c-b56153

16

Çoklu bağlamalar için .NET 4'ten beri dikkat etmeniz gerekir.

Aşağıda .NET 4.6 ile test edilmiş kısa bir genel bakış:

Normal ciltleme:

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

Çoklu bağlama:

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

veya kullanabileceğiniz " yerine ' MultiBinding içinde:

<MultiBinding StringFormat='{}{0:hh":"mm":"ss} -> {1:hh":"mm":"ss}'>

Not: kullanarak = StringFormat "{: ss \: \: dd \: 0 ss} {} -> {1: ss \: dd \: ss}" olacak değil bir MultiBinding üzerinde çalışma, bu boş bir sonucu sonuçlanacaktır.


13

Bu sorunun artık eski olduğunun farkındayım, ancak kimsenin doğrudan StringFormatüzerinde çalışacak bu basitliği önermesine şaşırdım TimeSpan:

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

2
Bu konuda çok fazla kafa karışıklığı var. Görünüşe göre sözdizimi .NET 4 ile değişmiş olabilir.
McGarnagle


11

StringFormat'ı Content özelliğini kullanan bir Etikette kullanmak istiyorsanız, zaman aralığınızı formatlamak için ContentStringFormat'ı kullanabilirsiniz :

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

1
Ne Cevabınız belirtmeleri çifte vurgulama hak: kullanmak XAML kontrollerde Contentözelliği (yani değil Textörneğin olarak mülkiyet, bir TextBlock), mülkiyet ContentStringFormat gerekir kullanılabilir. Bağlamanın bir StringFormatparçası olarak belirtmek işe yaramaz.
Informagic

3

Milisaniye ile TimeSpan StringFormat:

<TextBlock Text="{Binding MyTime, StringFormat=\{0:hh\\:mm\\:ss\\.fff\}}"/>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.