ใช้ StringFormat เพื่อเพิ่มสตริงในการโยง WPF XAML


125

ฉันมีแอปพลิเคชัน WPF 4 ที่มี TextBlock ซึ่งมีการผูกทางเดียวกับค่าจำนวนเต็ม (ในกรณีนี้อุณหภูมิเป็นองศาเซลเซียส) XAML มีลักษณะดังนี้:

<TextBlock x:Name="textBlockTemperature">
        <Run Text="{Binding CelsiusTemp, Mode=OneWay}"/></TextBlock>

ใช้งานได้ดีสำหรับการแสดงค่าอุณหภูมิจริง แต่ฉันต้องการจัดรูปแบบค่านี้เพื่อให้รวม° C แทนที่จะเป็นเพียงตัวเลข (30 ° C แทนที่จะเป็นเพียง 30) ฉันอ่านเกี่ยวกับ StringFormat มาแล้วและฉันได้เห็นตัวอย่างทั่วไปหลายอย่างเช่นนี้:

// format the bound value as a currency
<TextBlock Text="{Binding Amount, StringFormat={}{0:C}}" />

และ

// preface the bound value with a string and format it as a currency
<TextBlock Text="{Binding Amount, StringFormat=Amount: {0:C}}"/>

น่าเสียดายที่ไม่มีตัวอย่างใดที่ฉันเห็นได้ต่อท้ายสตริงเข้ากับค่าที่ถูกผูกไว้อย่างที่ฉันพยายามทำ ฉันแน่ใจว่ามันต้องเป็นอะไรที่เรียบง่าย แต่ฉันไม่มีโชคเลย ใครช่วยอธิบายวิธีการทำ

คำตอบ:


218

ตัวอย่างแรกของคุณคือสิ่งที่คุณต้องการอย่างมีประสิทธิภาพ:

<TextBlock Text="{Binding CelsiusTemp, StringFormat={}{0}°C}" />

20
ทำไมรูปแบบสตริงใน XAML จะมีที่ว่างเปล่าชั้นนำ{}?
Jonesopolis

6
@ Jonesopolis อยู่ในเอกสาร - แต่ถ้าสตริงรูปแบบของคุณเริ่มต้นด้วย a {จะมีกลไกในการหลบหนีเนื่องจาก{}มีความหมายใน xaml อยู่แล้ว
Reed Copsey

5
ฉันไม่เห็นว่าเอกสารอธิบายส่วนนำ {} อยู่ที่ไหน
Eric

5
@Eric เหมือนเอกสารมากมันเหม็น - พวกเขาสาธิต แต่ไม่อธิบาย
Reed Copsey

19
ที่นี่เอกสารลึกลับ {}: msdn.microsoft.com/en-us/library/ms744986.aspx
Jotrius

107

นี่เป็นอีกทางเลือกหนึ่งที่ใช้งานได้ดีสำหรับการอ่านหากคุณมี Binding ตรงกลางสตริงหรือการโยงหลาย ๆ

<TextBlock>
  <Run Text="Temperature is "/>
  <Run Text="{Binding CelsiusTemp}"/>
  <Run Text="°C"/>  
</TextBlock>

<!-- displays: 0°C (32°F)-->
<TextBlock>
  <Run Text="{Binding CelsiusTemp}"/>
  <Run Text="°C"/>
  <Run Text=" ("/>
  <Run Text="{Binding Fahrenheit}"/>
  <Run Text="°F)"/>
</TextBlock>

6
ฉันชอบคำตอบนี้ดีกว่าเล็กน้อยเพราะฉันสามารถแทรกข้อความจากไลบรารีสตริงได้อย่างง่ายดาย แน่นอนถ้าคุณกังวลเกี่ยวกับความเป็นสากลจริงๆคุณอาจจะใช้ตัวแปลงได้ดีกว่าดังนั้นลำดับของจำนวนและหน่วยจึงไม่ได้รับการแก้ไข <Run Text = "{x: Static s: UIStrings.General_FahrenheitAb อักษรย่อ}" />
Matt Becker

1
นี่เป็นวิธีแก้ปัญหาที่ยอดเยี่ยม แต่ฉันได้รับช่องว่างเพิ่มเติมในการแสดงข้อความสุดท้ายระหว่าง Text Runs - มีความคิดอย่างไร ในตัวอย่างของคุณฉันเห็น0 °C ( 32 °F)
Conrad

ไม่มีประโยชน์อย่างยิ่งหากคุณต้องการจัดรูปแบบสตริงจริง (เช่นควบคุมจำนวนตำแหน่งทศนิยม ฯลฯ )
BrainSlugs83

5
@Conrad หากคุณไม่ต้องการให้มีช่องว่างระหว่างการวิ่งแต่ละครั้งคุณควรวางการวิ่งเหล่านั้นไว้ในบรรทัดเดียวดังนี้: <TextBlock> <Run Text = "{Binding CelsiusTemp}" /> <Run Text = "° C" / > <Run Text = "(" /: <Run Text = "{Binding Fahrenheit}" /> <Run Text = "° F)" /> </TextBlock>
Ladislav Ondris

94

โปรดทราบว่าการใช้ StringFormat ในการเชื่อมโยงดูเหมือนจะใช้ได้กับคุณสมบัติ "ข้อความ" เท่านั้น ใช้สิ่งนี้สำหรับฉลากเนื้อหาจะไม่ทำงาน


16
มากจุดสำคัญที่เอาฉันพยายามจนฉันได้หมดหวังและพบความคิดเห็นนี้เพื่อตรวจสอบความสงสัยของฉัน
DonBoitnott

64
ContentStringFormatมาช่วยเหลือตัวอย่าง: Content="{Binding Path=TargetProjects.Count}" ContentStringFormat="Projects: {0}".
astrowalker

2
ขอบคุณแคสเปอร์ฮีโร่ตัวจริงสำหรับการโพสต์ข้อมูลนั้น
DaWiseguy

5
สำหรับส่วนหัว GridViewColumn ให้ใช้HeaderStringFormat="{}{0} For Report"
เฟลิกซ์

2
หากคุณกำลังใช้ข้อมูลเวลาออกแบบดูเหมือนว่าคุณจะต้องสร้างโครงการใหม่หลังจากแก้ไข ContentStringFormat เพื่อรับการเปลี่ยนแปลงเพื่อแสดงในตัวออกแบบในขณะที่ StringFormat ที่ใช้ในการบอกว่ากล่องข้อความจะอัปเดตตัวออกแบบแบบเรียลไทม์
Richard Moore

-8

ใน xaml

<TextBlock Text="{Binding CelsiusTemp}" />

ในViewModelวิธีนี้การตั้งค่ายังทำงาน:

 public string CelsiusTemp
        {
            get { return string.Format("{0}°C", _CelsiusTemp); }
            set
            {
                value = value.Replace("°C", "");
              _CelsiusTemp = value;
            }
        }

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