Como vincular vários valores a um único WPF TextBlock?

210

Atualmente, estou usando o TextBlockabaixo para vincular o valor de uma propriedade chamada Name:

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

Agora, quero vincular outra propriedade chamada IDà mesma TextBlock.

É possível vincular dois ou mais valores ao mesmo TextBlock? Isso pode ser feito com concatenação simples, como Name + IDe, se não, como mais isso poderia ser abordado?

Gastar
fonte

Respostas:

434

Você pode usar um MultiBindingcombinado com a StringFormatpropriedade O uso seria semelhante ao seguinte:

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

Dando Nameum valor de Fooe IDum valor de 1, sua saída no TextBlock seria então Foo + 1.

Note: que isso só é suportado no .NET 3.5 SP1 e 3.0 SP2 ou posterior.

Richard McGuire
fonte
5
@ Pre - Na verdade, não tenho certeza se o '{}' é necessário neste caso, incluí-o desde que foi usado no exemplo do MSDN. No entanto, em geral, é necessário como uma sequência de escape para o analisador XAML, para evitar confusão com a extensão de marcação Binding.
Richard McGuire
2
Há um efeito colateral nisso. Se você usar esse método em algo como um DataGridcomportamento de classificação, infelizmente não funcionará. Uma solução mais apropriada seria criar uma propriedade somente leitura em seu modelo com o formato de sequência apropriado para o qual vincular. Escusado será dizer que esta é uma maneira elegante de formatar rapidamente, embora um pouco detalhado.
Brett Ryan
34
você só precisa de {} quando a string de formato começa com o parâmetro {0}, não é necessário se a string de formato começar com um texto. ex: "{} {0} + {1}" "Página {0} de {1}"
Dakianth 20/06/16
Não funcionou em um projeto do WPF .Net 4.0 Visual Studio 2017.
Sorush 26/19
A solução de @ Patrick funcionou para mim. Não consegui fazer isso funcionar. Eu tive esse erroXamlParseException: 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
127

Sei que é tarde demais, mas pensei em acrescentar outra maneira de fazer isso.

Você pode tirar proveito do fato de que a propriedade Text pode ser configurada usando " Run s", para que você possa configurar várias ligações usando uma Run para cada uma. Isso é útil se você não tiver acesso ao MultiBinding (que eu não encontrei ao desenvolver para o Windows Phone)

<TextBlock>
  <Run Text="Name = "/>
  <Run Text="{Binding Name}"/>
  <Run Text=", Id ="/>
  <Run Text="{Binding Id}"/>
</TextBlock>
Patrick
fonte
4
Essa é uma abordagem muito útil a ser usada ao vincular a várias seqüências originadas como DynamicResource, pois você não pode usar uma MultiBinding com StringFormat para isso.
slugster
Eu apenas tentei isso. Funciona, no entanto, todo elemento (mesmo geometria) que é desenhado (em uma atualização) agora pisca cada carrapato por algum motivo. Indo tentar o outro método.
Logan Klenner
6
Isso pode ficar difícil se o texto tiver que ser localizado porque o pedido está codificado.
BLUEM
1
Outro uso desta abordagem é a aplicação de estilo diferente para cada ligação
Hamid Naeemi
melhor resposta para 2019
Fábio BC Souza
23

Se estes forem apenas blocos de texto (e, portanto, uma ligação unidirecional) e você quiser concatenar valores, basta vincular dois blocos de texto e colocá-los em um painel de pilha horizontal.

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

Isso exibirá o texto (que é o que todos os Textblocks fazem) sem precisar fazer mais nenhuma codificação. Você pode colocar uma pequena margem neles para fazê-los parecer certos.

CodeWarrior
fonte
11

Use um 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;
    }
}

e na marcação

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

. . .

<TextBlock Text="{Binding Name, Converter={StaticResource MyConverter Parameter=ID}}" />
Preet Sangha
fonte
Sim - isso foi escrito há 6 anos e você está vinculando o "Nome" como o primeiro argumento ao conversor (chamado valor no código) e o ID (uma sequência da pergunta) como o segundo argumento.
Preet Sangha