Come associare più valori a un singolo TextBlock WPF?


210

Attualmente sto usando il TextBlockseguente per associare il valore di una proprietà denominata Name:

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

Ora, voglio associare un'altra proprietà denominata IDalla stessa TextBlock.

È possibile associare due o più valori allo stesso TextBlock? Può essere fatto con una semplice concatenazione, come Name + IDe, in caso contrario, in quale altro modo potrebbe essere affrontato?

Risposte:


434

È possibile utilizzare un MultiBindingcombinato con la StringFormatproprietà. L'utilizzo sarebbe simile al seguente:

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

Dare Nameun valore di Fooe IDun valore di 1, sarebbe quindi l'output in TextBlock Foo + 1.

Note: che questo è supportato solo in .NET 3.5 SP1 e 3.0 SP2 o versioni successive.


5
@Preet - In realtà non sono sicuro che "{}" sia necessario in questo caso, l'ho incluso poiché è stato utilizzato nell'esempio MSDN. In generale, tuttavia, è necessario come sequenza di escape per il parser XAML per evitare confusione con l'estensione di markup Binding.
Richard McGuire,

2
C'è un effetto collaterale in questo. Se si utilizza questo metodo in qualcosa come un DataGridcomportamento di ordinamento, purtroppo non funziona. Una soluzione più appropriata sarebbe quella di creare una proprietà di sola lettura nel modello con il formato stringa appropriato a cui eseguire il binding. Inutile dire che questo è un modo pulito per formattare rapidamente anche se un po 'prolisso.
Brett Ryan,

34
hai solo bisogno di {} quando la stringa di formato inizia con il parametro {0}, non è necessaria se la stringa di formato inizia con un testo. es: "{} {0} + {1}" "Pagina {0} di {1}"
Dakianth

Non ha funzionato su un progetto WPF .Net 4.0 Visual Studio 2017.
Sorush

@ La soluzione di Patrick ha funzionato per me. Non sono riuscito a farlo funzionare. Ho avuto questo erroreXamlParseException: 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

So che è tardi, ma ho pensato di aggiungere un altro modo per farlo.

Puoi trarre vantaggio dal fatto che la proprietà Text può essere impostata utilizzando " Esegui s", in modo da poter impostare più associazioni utilizzando una Esegui per ognuna. Questo è utile se non hai accesso a MultiBinding (che non ho trovato durante lo sviluppo per Windows Phone)

<TextBlock>
  <Run Text="Name = "/>
  <Run Text="{Binding Name}"/>
  <Run Text=", Id ="/>
  <Run Text="{Binding Id}"/>
</TextBlock>

4
Questo è un approccio molto utile da usare quando si esegue il binding a più stringhe che vengono fornite come DynamicResource poiché non è possibile utilizzare un MultiBinding con StringFormat per questo.
slugster

Ho appena provato questo. Funziona, tuttavia ogni elemento (anche la geometria) che viene disegnato (su un aggiornamento) ora lampeggia ogni segno di spunta per qualche motivo. Andando a provare l'altro metodo.
Logan Klenner,

6
Questo può diventare difficile se il testo deve essere localizzato perché l'ordine è hardcoded.
BlueM,

1
Un altro uso di questo approccio è applicare uno stile diverso per ogni rilegatura
Hamid Naeemi

migliore risposta per il 2019
Fábio BC Souza,

23

Se questi saranno solo blocchi di testo (e quindi rilegatura in un modo), e vuoi solo concatenare i valori, basta associare due blocchi di testo e metterli in un pannello orizzontale.

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

Ciò visualizzerà il testo (che fanno tutti i blocchi di testo) senza dover fare altro codice. Potresti mettere un piccolo margine su di loro per farli sembrare giusti però.


11

Utilizzare 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;
    }
}

e nel markup

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

. . .

<TextBlock Text="{Binding Name, Converter={StaticResource MyConverter Parameter=ID}}" />

Sì, questo è stato scritto 6 anni fa e stai associando il "Nome" come primo argomento al convertitore (chiamato valore nel codice) e l'ID (una stringa dalla domanda) come secondo argomento.
Preet Sangha,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.