Use StringFormat para agregar una cadena a un enlace WPF XAML


124

Tengo una aplicación WPF 4 que contiene un TextBlock que tiene un enlace unidireccional a un valor entero (en este caso, una temperatura en grados Celsius). El XAML se ve así:

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

Esto funciona bien para mostrar el valor de temperatura real, pero me gustaría formatear este valor para que incluya ° C en lugar de solo el número (30 ° C en lugar de solo 30). He estado leyendo sobre StringFormat y he visto varios ejemplos genéricos como este:

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

y

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

Desafortunadamente, ninguno de los ejemplos que he visto ha agregado una cadena al valor enlazado como estoy tratando de hacer. Estoy seguro de que debe ser algo simple, pero no tengo suerte de encontrarlo. ¿Alguien puede explicarme cómo hacer eso?

Respuestas:


217

Su primer ejemplo es efectivamente lo que necesita:

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

20
¿Por qué el formato de cadena en xaml tiene el inicio vacío {}?
Jonesopolis

66
@Jonesopolis Está en los documentos, pero si la cadena de formato comienza con a {, proporciona un mecanismo para escapar, ya que {}ya tiene significado en xaml.
Reed Copsey

55
No veo dónde la documentación explica los principales {}.
Eric

55
@Eric Al igual que mucha documentación, apesta: la muestran, pero no explican.
Reed Copsey

19
aquí la documentación del misterioso {}: msdn.microsoft.com/en-us/library/ms744986.aspx
Jotrius

106

Aquí hay una alternativa que funciona bien para la legibilidad si tiene el enlace en el medio de la cadena o enlaces múltiples:

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

66
Me gusta esta respuesta un poco mejor porque puedo insertar texto de una biblioteca de cadenas fácilmente. Por supuesto, si realmente le preocupa la internacionalización, probablemente sea mejor usar un convertidor para que el orden del número y las unidades no sea fijo. <Run Text = "{x: Static s: UIStrings.General_FahrenheitAbbreviation}" />
Matt Becker

1
Esta es una gran solución, pero obtengo espacios adicionales en la pantalla de texto final, entre las ejecuciones de texto, ¿alguna idea de por qué? En su ejemplo veo0 °C ( 32 °F)
Conrad

No es súper útil si desea hacer un formato de cadena real (es decir, controlar el número de lugares decimales, etc.).
BrainSlugs83

55
@Conrad Si no desea los espacios entre cada ejecución, debe colocar esas ejecuciones en una sola línea de la siguiente manera: <TextBlock> <Run Text = "{Binding CelsiusTemp}" /> <Run Text = "° C" / > <Run Text = "(" /: <Run Text = "{Binding Fahrenheit}" /> <Run Text = "° F)" /> </TextBlock>
Ladislav Ondris

92

Tenga en cuenta que el uso de StringFormat en enlaces solo parece funcionar para propiedades de "texto". Usar esto para Label.Content no funcionará


15
Un punto MUY importante que me llevó a intentarlo hasta que me desesperé y encontré este comentario para validar mi sospecha.
DonBoitnott

64
ContentStringFormatviene al rescate, ejemplo: Content="{Binding Path=TargetProjects.Count}" ContentStringFormat="Projects: {0}".
astrowalker

2
Gracias Casper, verdadero héroe por publicar esa información.
DaWiseguy

55
para encabezados GridViewColumn, useHeaderStringFormat="{}{0} For Report"
Felix

2
Si está utilizando datos de tiempo de diseño, parece que necesita reconstruir el proyecto después de editar ContentStringFormat para que los cambios se reflejen en el diseñador, mientras que StringFormat, como se usa en un cuadro de texto, actualizará el diseñador en tiempo real.
Richard Moore

-8

En xaml

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

De ViewModelesta manera, establecer el valor también funciona:

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

19
Esto va en contra del punto de separación de View-Viewmodel
Askolein
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.