¿Cómo vincular múltiples valores a un único WPF TextBlock?

210

Actualmente estoy usando lo TextBlocksiguiente para vincular el valor de una propiedad llamada Name:

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

Ahora, quiero vincular otra propiedad IDcon el mismo nombre TextBlock.

¿Es posible vincular dos o más valores a la misma TextBlock? ¿Se puede hacer con una simple concatenación, como Name + IDy, de no ser así, cómo podría abordarse esto?

Gastar
fuente

Respuestas:

434

Puede usar un MultiBindingcombinado con la StringFormatpropiedad. El uso sería similar al siguiente:

<TextBlock>
    <TextBlock.Text>    
        <MultiBinding StringFormat="{}{0} + {1}">
            <Binding Path="Name" />
            <Binding Path="ID" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

Dando Nameun valor de Fooy IDun valor de 1, su salida en TextBlock sería entonces Foo + 1.

Note: que esto solo es compatible con .NET 3.5 SP1 y 3.0 SP2 o posterior.

Richard McGuire
fuente
55
@Preet: en realidad no estoy seguro de si el '{}' es necesario en este caso, lo incluí ya que se usó en la muestra de MSDN. Sin embargo, en general, se necesita como una secuencia de escape para el analizador XAML para evitar confusiones con la extensión de marcado Binding.
Richard McGuire
2
Hay un efecto secundario en esto. Si utiliza este método en algo así como un DataGridcomportamiento de clasificación, lamentablemente no funciona. Una solución más apropiada sería crear una propiedad de solo lectura en su modelo con el formato de cadena apropiado para enlazar. No hace falta decir que esta es una buena forma de formatear rápidamente, aunque sea un poco detallado.
Brett Ryan
34
solo necesita {} cuando la cadena de formato comienza con el parámetro {0}, no es necesario si la cadena de formato comienza con un texto. ej .: "{} {0} + {1}" "Página {0} de {1}"
Dakianth
No funcionó en un proyecto de WPF .Net 4.0 Visual Studio 2017.
Sorush
La solución de @ Patrick funcionó para mí. No pude hacer que esto funcione. Tuve este errorXamlParseException: A 'Binding' cannot be set on the 'Path' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
Tyson Williams, el
127

Sé que esto es un poco tarde, pero pensé que agregaría otra forma de hacerlo.

Puede aprovechar el hecho de que la propiedad Text se puede establecer usando " Ejecutar s", por lo que puede configurar varios enlaces usando una Ejecución para cada uno. Esto es útil si no tiene acceso a MultiBinding (que no encontré al desarrollar para Windows Phone)

<TextBlock>
  <Run Text="Name = "/>
  <Run Text="{Binding Name}"/>
  <Run Text=", Id ="/>
  <Run Text="{Binding Id}"/>
</TextBlock>
Patricio
fuente
44
Este es un enfoque muy útil para usar cuando se vinculan varias cadenas que se obtienen como DynamicResource, ya que no puede usar un MultiBinding con StringFormat para eso.
slugster
Acabo de intentar esto. Funciona, sin embargo, cada elemento (incluso la geometría) que se dibuja (en una actualización) ahora parpadea en cada tic por alguna razón. Voy a probar el otro método.
Logan Klenner
66
Esto puede ser difícil si el texto tiene que ser localizado porque el orden está codificado.
BlueM
1
Otro uso de este enfoque es aplicar un estilo diferente para cada enlace
Hamid Naeemi el
mejor respuesta para 2019
Fábio BC Souza
23

Si estos solo van a ser bloques de texto (y, por lo tanto, un enlace unidireccional), y solo desea concatenar valores, solo enlace dos bloques de texto y colóquelos en un panel de pila horizontal.

    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Name}"/>
        <TextBlock Text="{Binding ID}"/>
    </StackPanel>

Eso mostrará el texto (que es todo lo que hacen los bloques de texto) sin tener que hacer más codificación. Sin embargo, puede poner un pequeño margen para que se vean bien.

CodeWarrior
fuente
11

Use un ValueConverter

[ValueConversion(typeof(string), typeof(String))]
public class MyConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return string.Format("{0}:{1}", (string) value, (string) parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {

        return DependencyProperty.UnsetValue;
    }
}

y en el marcado

<src:MyConverter x:Key="MyConverter"/>

. . .

<TextBlock Text="{Binding Name, Converter={StaticResource MyConverter Parameter=ID}}" />
Sangha Preet
fuente
Sí, esto se escribió hace 6 años, y está vinculando el "Nombre" como el primer argumento para el convertidor (llamado valor en el código), y la ID (una cadena de la pregunta) como el segundo argumento.
Preet Sangha