2009-02-12 8 views
67

Je souhaite afficher une liste d'objets Client dans un objet ItemsControl WPF. J'ai créé un DataTemplate pour cela:Concaténer les chaînes au lieu d'utiliser une pile de TextBlocks

<DataTemplate DataType="{x:Type myNameSpace:Customer}"> 
     <StackPanel Orientation="Horizontal" Margin="10"> 
      <CheckBox"></CheckBox> 
      <TextBlock Text="{Binding Path=Number}"></TextBlock> 
      <TextBlock Text=" - "></TextBlock> 
      <TextBlock Text="{Binding Path=Name}"></TextBlock> 
     </StackPanel> 
    </DataTemplate> 

donc ce que je veux est essentiellement une liste simple (avec des cases à cocher) qui contient le numéro - NOM. N'y a-t-il pas un moyen de concaténer le numéro et le nom directement dans la partie Liaison?

Répondre

140

Il existe une propriété StringFormat (dans .NET 3.5 SP1) que vous pouvez probablement utiliser. Et utile sheat de triche de liaison WPF peut trouvé here. Si cela ne vous aide pas, vous pouvez toujours écrire votre propre ValueConverter ou propriété personnalisée pour votre objet.

Juste coché, vous pouvez utiliser StringFormat avec multibinding. Dans votre code cas sera quelque chose comme ceci:

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

je devais commencer chaîne de format avec l'espace, sinon Visual Studio ne construirait pas, mais je pense que vous trouverez ainsi contourner :)

Modifier
L'espace est requis dans StringFormat pour empêcher l'analyseur de traiter {0} comme une liaison réelle. Autres alternatives:

<!-- use a space before the first format --> 
<MultiBinding StringFormat=" {0} - {1}"> 

<!-- escape the formats --> 
<MultiBinding StringFormat="\{0\} - \{1\}"> 

<!-- use {} before the first format --> 
<MultiBinding StringFormat="{}{0} - {1}"> 
+24

Au lieu de l'espace, vous pouvez utiliser {}, par ex. StringFormat = "{} {0} - {1}" –

+0

Merci, je ne le savais pas! :) – PiRX

+0

Ceci est utile, merci pour tout! –

3

Vous pouvez également utiliser une exécution lisible. Des trucs utiles, surtout si l'on veut ajouter un peu de formatage de texte (couleurs, grammage, etc.).

<TextBlock> 
    <something:BindableRun BoundText="{Binding Number}"/> 
    <Run Text=" - "/> 
    <something:BindableRun BoundText="{Binding Name}"/> 
</TextBlock> 

Here's une classe d'origine:
Here quelques améliorations supplémentaires.
Et c'est tout en un seul morceau de code:

public class BindableRun : Run 
    { 
     public static readonly DependencyProperty BoundTextProperty = DependencyProperty.Register("BoundText", typeof(string), typeof(BindableRun), new PropertyMetadata(new PropertyChangedCallback(BindableRun.onBoundTextChanged))); 

     private static void onBoundTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      ((Run)d).Text = (string)e.NewValue; 
     } 

     public String BoundText 
     { 
      get { return (string)GetValue(BoundTextProperty); } 
      set { SetValue(BoundTextProperty, value); } 
     } 

     public BindableRun() 
      : base() 
     { 
      Binding b = new Binding("DataContext"); 
      b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(FrameworkElement), 1); 
      this.SetBinding(DataContextProperty, b); 
     } 
    } 
36

Si vous souhaitez concaténer une valeur dynamique avec un texte statique, essayez ceci:

<TextBlock Text="{Binding IndividualSSN, StringFormat= '\{0\} (SSN)'}"/> 

Affiche: 234-334- 5566 (NSS)

+1

Quel est le contenu de TextBlockLeftStyle? – itsho

+0

C'est un style personnalisé que je dois aligner le bloc de texte à gauche. Cela n'a aucune signification ici. – redskull

7

Voir l'exemple suivant, utilisé dans mon code en utilisant la classe Run:

 <TextBlock x:Name="..." Width="..." Height="..." 
      <Run Text="Area="/> 
      <Run Text="{Binding ...}"/> 
      <Run Text="sq.mm"/> 
      <LineBreak/> 
      <Run Text="Min Diameter="/> 
      <Run Text="{Binding...}"/> 
      <LineBreak/> 
      <Run Text="Max Diameter="/> 
      <Run Text="{Binding...}"/> 
     </TextBlock > 
Questions connexes