วิธีจัดรูปแบบ TimeSpan ใน XAML


94

ฉันพยายามจัดรูปแบบบล็อกข้อความที่เชื่อมโยงกับ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


คุณจำได้ไหมว่าคุณใช้งาน. Net เวอร์ชันใดในปี 2010 ฉันมีปัญหาคล้ายกันกับ Windows Phone XAML: stackoverflow.com/q/18679365/1001985
McGarnagle

หมายเหตุ: {} ที่จุดเริ่มต้นของรูปแบบทั้งหมดเป็นลำดับการหลีกเลี่ยงไม่ใช่ตัวระบุรูปแบบ ทำให้ XAML ทนต่อวงเล็บเพิ่มเติมในรูปแบบโดยไม่ต้องใช้แบ็กสแลช
Grault

คำตอบ:


90

ใน. NET 3.5 คุณสามารถใช้ MultiBinding แทนได้

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

อัปเดต
เพื่อตอบความคิดเห็น

เพื่อให้แน่ใจว่าคุณแสดงตัวเลข 2 หลักแม้ว่าชั่วโมงหรือนาทีจะเป็น 0-9 คุณสามารถใช้ {0:00} แทน {0} ได้ สิ่งนี้จะทำให้แน่ใจว่าเอาต์พุตสำหรับเวลา 12:01 คือ 12:01 แทนที่จะเป็น 12: 1
หากคุณต้องการส่งออก 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
ผลลัพธ์จะไม่เป็น "10: 1" หรือ "4: 9" ถ้าส่วนของนาทีมีเพียงตัวเลขเดียว
Cygon

@Cygon: ดูคำตอบที่อัปเดตของฉันสำหรับวิธีแก้ไขปัญหานี้ ใช้ {0: D2} แทน {0}
Fredrik Hedblad

ผลลัพธ์นี้จะแสดงผล "-07: -12" สำหรับ Timeduration ที่เป็นลบ 7 ชั่วโมง 12 นาที หากระยะเวลาลบ 7 ชั่วโมงผลลัพธ์จะเป็น "-07: 00" แต่ทันทีที่มีนาทีที่ไม่เป็นศูนย์ในช่วงเวลาเชิงลบลบจะถูกผนวกเข้า.Hoursกับ.Minutes
tzippy

@FredrikHedblad ฉันต้องการแสดงTotalMinutesแทนที่จะMinutesเป็นส่วนนาที (เพื่อแสดงช่วงเวลาที่ยาวที่สุด 1 ชั่วโมง) แต่TotalMinutesคุณสมบัติอยู่ในรูปแบบสองเท่าดังนั้นการเชื่อมโยงโดยใช้<Binding Path="MyTime.TotalMinutes" />ผลลัพธ์แบบปัดเศษซึ่งไม่ดี - ฉันต้องแสดงค่าที่ถูกตัดทอนแทนที่จะปัดเศษ เป็นไปได้ที่จะบรรลุโดยไม่ใช้ตัวแปลงค่าที่กำหนดเองเพื่อตัดทอน double เป็น int?
Dominik Palo

144

สตริงรูปแบบมีไว้เพื่อใช้กับ a DateTimeไม่ใช่ไฟล์TimeSpan.

คุณสามารถเปลี่ยนรหัสเพื่อใช้งานDateTime.Nowแทนได้ xaml ของคุณสบายดี:

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

อัปเดต

และจาก. Net 4 จัดรูปแบบTimeSpanดังนี้:

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

ใช่ ... แต่ฉันกำลังมองหาวิธีที่จะจัดรูปแบบค่า Timespan ได้
biju

1
ฉันกำลังกรองช่วงเวลาของฉันจากการรวบรวมวันที่โดยแยกความแตกต่างการเรียงลำดับ .. สีน้ำเงิน .. เป็นไปตามที่ตรรกะของฉันดำเนินไป
biju

@biju ฉันได้อัปเดตตัวอย่างด้วยสตริงรูปแบบสำหรับ TimeSpan
Tim Lloyd

2
ฉันไม่รู้ว่าฉันทำอะไรผิดหรือเปล่า.. แต่มันก็ยังใช้ไม่ได้สำหรับฉันที่นี่ VisualStudio 2008, Framework 3.5
biju

1
นี่คือคำตอบที่ถูกต้องไม่ใช่คำตอบที่ระบุไว้ด้านบน แม้แต่ dot net 3.5 ก็ใช้ตัวแปลงแทนคำตอบที่แนะนำ
MikeKulls

44

เพื่อเพิ่มลงในพูลฉันประสบความสำเร็จในการใช้การผูกนี้เพื่อแสดง TimeSpan ในแอป WPF ที่ใช้งานจริง:

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

ลองพยายามทำให้แบ็กสแลชถูกต้อง :)


5
หากคุณต้องการไปที่เศษส่วนของวินาทีคุณต้องหลีกเลี่ยงเครื่องหมายจุลภาคด้วย: {0: hh \\: mm \\: ss \\. ffff}
Rashack

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

ความผิดพลาดครั้งใหญ่ของฉันตลอดเวลาคือฉันใช้ H เช่นสตริงรูปแบบ DateTime แต่เห็นได้ชัดว่าไม่มีรูปแบบ 12/24 สำหรับ TimeSpan ...
M Stoerzel

21

StringFormatต้องอยู่ในรูปแบบของสตริงรูปแบบ ในกรณีนี้จะมีลักษณะดังนี้:

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

หมายเหตุ: หากคุณต้องการแสดงจำนวนชั่วโมงและนาทีและช่วงเวลาเกิดขึ้นเป็นมากกว่า 24 ชั่วโมงมีข้อแม้กับวิธีการของคุณ: นี่เป็นวิธีแก้ปัญหา


@biju - ปรับปรุงไวยากรณ์ ไม่มีเครื่องหมายคำพูดเดียวรอบ ๆ ค่า StringFormat
Peter Lillevold

และใช่ตามที่ตัวอย่างของ @chibacity แสดงให้เห็นว่า \ จำเป็นต้องมีสองเท่าเพื่อหลีกเลี่ยง:
Peter Lillevold

1
และแน่นอนสิ่งนี้ใช้ได้เฉพาะใน. Net 4.0! สตริงรูปแบบถูกละเว้นโดยสิ้นเชิงใน. Net 3.5
Peter Lillevold

2
โปรดทราบว่าสิ่งนี้ใช้ได้กับ TextBlock แต่ไม่ใช่ (!) ที่มีป้ายกำกับ
โตงเตง

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 = "{} {0: hh \: \: mm \: 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

12

ตอนนี้ WPF ใน. NET 4 มีช่วงเวลาจากสตริง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

อาจจะเป็นเรื่องจริงในเดือนกุมภาพันธ์ 2555 แต่มันไม่ใช่อีกต่อไป
Sheridan

11

หากคุณต้องการใช้ StringFormat ในป้ายกำกับที่ใช้คุณสมบัติเนื้อหาคุณสามารถใช้ContentStringFormatเพื่อจัดรูปแบบช่วงเวลาของคุณ:

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

1
สิ่งที่คุณระบุในคำตอบของคุณสมควรได้รับการไฮไลต์สองครั้ง: ในตัวควบคุม XAML ที่ใช้Contentคุณสมบัติ (เช่นไม่ใช่Textคุณสมบัติเช่นกTextBlock) ContentStringFormat ต้องใช้คุณสมบัติ การระบุStringFormatเป็นส่วนหนึ่งของการผูกจะใช้ไม่ได้
Informagic

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.