Cách định dạng TimeSpan trong XAML


92

Tôi đang cố gắng định dạng một khối văn bản được liên kết với một thuộc TimeSpantính. Nó hoạt động nếu thuộc tính là loại DateTimenhưng nó không thành công nếu thuộc tính a TimeSpan. Tôi có thể hoàn thành nó bằng cách sử dụng một công cụ chuyển đổi. Nhưng tôi đang cố gắng tìm hiểu xem có lựa chọn thay thế nào không.

Mã mẫu:

public TimeSpan MyTime { get; set; }

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

Xaml

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

Tôi đang mong đợi khối văn bản chỉ hiển thị giờ và phút. Nhưng nó đang hiển thị là:

19: 10: 46.8048860


Bạn có nhớ mình đã chạy phiên bản .Net nào vào năm 2010 không? Tôi đang gặp sự cố tương tự với Windows Phone XAML: stackoverflow.com/q/18679365/1001985
McGarnagle

Lưu ý: Dấu {} ở đầu tất cả các định dạng là một chuỗi thoát, không phải là mã định dạng. Nó khiến XAML dung nạp thêm các dấu ngoặc trong định dạng mà không yêu cầu dấu gạch chéo ngược.
Grault

Câu trả lời:


88

Trong .NET 3.5, bạn có thể sử dụng MultiBinding thay thế

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

Cập nhật
Để trả lời các ý kiến.

Để đảm bảo bạn xuất ra 2 chữ số ngay cả khi giờ hoặc phút là 0-9, bạn có thể sử dụng {0:00} thay vì {0}. Điều này sẽ đảm bảo đầu ra cho thời gian 12:01 là 12:01 thay vì 12: 1.
Nếu bạn muốn xuất 01:01 dưới dạng 1:01 sử dụngStringFormat="{}{0}:{1:00}"

Và Định dạngđiều kiện có thể được sử dụng để loại bỏ dấu âm trong vài phút. Thay vì {1:00}, chúng tôi có thể sử dụng {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: Cảm ơn bạn! Tôi đã ghi có câu trả lời của bạn nên tôi không thể làm lại :) Nhưng tôi thích câu hỏi hơn nên tôi có thể tìm lại giải pháp của bạn nếu tôi cần nó! Rất tốt đẹp là tốt
Fredrik Hedblad

1
Điều này sẽ không xuất ra "10: 1" hoặc "4: 9" nếu phần phút chỉ có một chữ số?
Cygon

@Cygon: Xem câu trả lời cập nhật của tôi để biết cách khắc phục sự cố này. Sử dụng {0: D2} thay vì {0}
Fredrik Hedblad

Kết quả này cho ra "-07: -12" cho Thời gian bão hòa âm là 7 giờ 12 phút. nếu thời lượng là trừ 7 giờ, đầu ra sẽ là "-07: 00". Nhưng ngay sau khi có một phút khác 0 trong khoảng thời gian âm, dấu trừ được thêm vào .Hourscũng như.Minutes
tzippy

@FredrikHedblad Tôi muốn hiển thị TotalMinutesthay vì Minutesdưới dạng phần phút (để hiển thị thời gian dài nhất là 1 giờ). Nhưng thuộc TotalMinutestính ở định dạng kép, vì vậy ràng buộc bằng cách sử dụng đầu <Binding Path="MyTime.TotalMinutes" />ra được làm tròn, điều này không tốt - tôi cần hiển thị giá trị bị cắt ngắn thay vì làm tròn. Có thể đạt được điều đó mà không cần sử dụng đồng hồ đo giá trị tùy chỉnh để cắt đôi thành int?
Dominik Palo

139

Chuỗi định dạng nhằm hoạt động trên DateTime , không phải a TimeSpan.

Bạn có thể thay đổi mã của mình để làm việc với DateTime.Now . Xaml của bạn vẫn ổn:

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

Cập nhật

Và từ .Net 4 định dạng a TimeSpannhư sau:

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

Có ... Nhưng tôi đang tìm cách nào đó để có thể định dạng giá trị Timespan.
biju

1
Tôi lọc một phần thời gian của tôi từ một bộ sưu tập của ngày, uống riêng biệt, sorting..blah..its cách logic của tôi đi
Biju

@biju Tôi đã cập nhật mẫu bằng chuỗi định dạng cho TimeSpan.
Tim Lloyd

2
Tôi không biết nếu tôi đang làm một cái gì đó wrong..but nó vẫn không làm việc cho tôi here.VisualStudio 2008, Framework 3.5
Biju

1
Đây là câu trả lời đúng, không phải câu được đánh dấu ở trên. Ngay cả đối với dot net 3.5 sử dụng công cụ chuyển đổi thay vì câu trả lời được đề xuất.
MikeKulls

44

Chỉ để thêm vào nhóm, tôi đang sử dụng thành công liên kết này để hiển thị TimeSpan trong ứng dụng WPF sản xuất:

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

Có một số cố gắng để có các dấu gạch chéo ngược đúng :)


5
Nếu bạn muốn chuyển đến phần giây, bạn cũng cần phải thoát khỏi dấu phẩy: {0: hh \\: mm \\: ss \\. Ffff}
Rashack

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

Sai lầm lớn của tôi trong suốt thời gian qua là tôi đã sử dụng H như chuỗi định dạng DateTime. Nhưng rõ ràng là không có định dạng 12/24 cho TimeSpan ...
M Stoerzel

22

StringFormatphải ở dạng chuỗi định dạng. Trong trường hợp này, nó sẽ giống như sau:

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

Lưu ý: nếu bạn muốn hiển thị tổng số giờ và phút và khoảng thời gian xảy ra lớn hơn 24 giờ, có một lưu ý với cách tiếp cận của bạn: Đây là một giải pháp .


@biju - cú pháp cập nhật. Thiếu dấu ngoặc kép xung quanh giá trị StringFormat.
Peter Lillevold

Và vâng, như chương trình mẫu @chibacity, một \ đôi được yêu cầu để thoát khỏi:
Peter Lillevold

1
và thực sự, điều này chỉ hoạt động trong .Net 4.0! Chuỗi định dạng hoàn toàn bị bỏ qua trong .Net 3.5.
Peter Lillevold

2
Cũng lưu ý rằng điều này hoạt động với TextBlock nhưng KHÔNG (!) Với Nhãn.
Xiềng xích

2
@Shacks StringFormat chỉ được sử dụng nếu mục tiêu của Binding là một thuộc tính kiểu String. Label.Content là Đối tượng, vì vậy nó bị bỏ qua. TextBlock.Text là một chuỗi, vì vậy nó được sử dụng.
15ee8f99-57ff-4f92-890c-b56153

16

Đối với nhiều ràng buộc, bạn cần phải chú ý kể từ .NET 4.

Tổng quan ngắn bên dưới, được thử nghiệm với .NET 4.6:

Ràng buộc thường xuyên:

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

Nhiều ràng buộc:

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

hoặc bạn có thể sử dụng " thay vì " trong đa liên kết:

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

Lưu ý: sử dụng StringFormat = "{} {0: hh \: \: mm \: ss} -> {1: hh \: mm \: ss}" sẽ không hoạt động trên MultiBinding, điều này sẽ dẫn đến kết quả trống.


13

Tôi biết rằng câu hỏi này hiện đã cũ, nhưng tôi ngạc nhiên rằng không ai đề xuất câu hỏi đơn giản StringFormatnày sẽ hoạt động TimeSpantrực tiếp trên:

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

2
Rất nhiều sự nhầm lẫn xung quanh điều này. Có vẻ như có thể cú pháp đã thay đổi với .NET 4.
McGarnagle

12

WPF trong .NET 4 hiện có khoảng thời gian từ chuỗi http://msdn.microsoft.com/en-us/library/ee372286.aspx

Tôi đang sử dụng cái sau <TextBlock FontSize="12" Text="{Binding Path=TimeLeft, StringFormat={}{0:g}}" />


1
Trên thực tế hoạt động trong .NET 4-4.5. Không có giải pháp nào khác trong chủ đề này làm được.
erodewald

Có thể điều đó đã đúng vào tháng 2 năm 2012, nhưng nó không còn nữa.
Sheridan

8

Nếu bạn muốn sử dụng StringFormat trong Nhãn sử dụng thuộc tính Nội dung, bạn có thể sử dụng ContentStringFormat để định dạng khoảng thời gian của mình:

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

Những gì bạn nêu trong câu trả lời của mình xứng đáng được đánh dấu kép: trong các điều khiển XAML sử dụng thuộc Contenttính (ví dụ: không phải thuộc Texttính như a TextBlock), thuộc tính ContentStringFormat phải được sử dụng. Chỉ định StringFormatlà một phần của ràng buộc sẽ không hoạt động.
Informagic

2

TimeSpan StringFormat với mili giây:

<TextBlock Text="{Binding MyTime, StringFormat=\{0:hh\\:mm\\:ss\\.fff\}}"/>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.