2010-10-22 24 views
3

J'essaye de formater un Tweet en utilisant la liaison de données. Ce que je dois faire est de diviser la valeur de texte du tweet en fonction du type de contenu. Je dois ajouter un peu de formatage de couleur à la partie http: // ... de la valeur du texte.Mise en forme de texte dans un TextBlock en utilisant uniquement DataBinding en XAML

Voici le kicker, je voudrais le faire en utilisant uniquement la liaison de données XAML.

<TextBlock x:Name="Tweet1" FontWeight="Bold" Height="207.236" 
    LineHeight="55" TextAlignment="Left" TextWrapping="Wrap" 
    Width="1614.646" Text="{Binding XPath=/statuses/status[2]/text}" 
    FontSize="56" FontFamily="Segoe Book" 
    Foreground="{DynamicResource TextColor-Gray}" /> 

// doit finir par ressembler à

<TextBlock x:Name="Tweet1" FontWeight="Bold" ... FontSize="56" FontFamily="Segoe Book"> 
    <Run Foreground="{DynamicResource TextColor-Gray}" >This is a Tweet with a hyperlink</Run> 
<Run Foreground="{DynamicResource TextColor-Pink}" >http://www.mysite.com</Run> 
</TextBlock> 

Voici un Regex je pourrais utiliser pour diviser la valeur de texte, mais je suis en train d'utiliser strictement DataBinding.

Regex regUrl = new Regex(@"/http:\/\/\S+/g"); 

Suggestions?

Répondre

1

Vous ne pouvez pas lier à Text et le remplacer par Run s car Text est de type String. , Vous auriez besoin au lieu de lier Inlines et de fournir un convertisseur qui analyse le texte (en utilisant votre regex, par exemple) et produit le Inlines approprié:

<TextBlock Inlines="{Binding XPath=/statuses/status[2]/text, Converter={StaticResource InlineConverter}}"/> 
+0

+1 Ne peut pas être fait comme le souhaite l'OP. – Ragepotato

+0

Ce que je pensais. Merci de confirmer. Je posterai mon convertisseur quand j'ai fini de le construire. – discorax

+4

Vous ne pouvez pas lier à Inlines. "La propriété Inlines est en lecture seule et ne peut pas être définie par le balisage" Toutes les autres suggestions? – discorax

2

J'utilise MVVMLight. Ce que j'ai fait est de capturer l'événement Loaded du TextBlock, et l'acheminer vers un "convertisseur".

using System.Collections.Generic; 
using System.Windows.Documents; 
using System.Windows.Controls; 

using GalaSoft.MvvmLight.Command; 

namespace Converters 
{ 
    public class MyInlineConverter 
    { 
     public RelayCommand<TextBlock> ConvertTextToInlinesCommand { get; private set; } 

     public MyInlineConverter() 
     { 
      ConvertTextToInlinesCommand = new RelayCommand<TextBlock>(textBlock => convertTextToInlines(textBlock)); 
     } 

     private static void convertTextToInlines(TextBlock textBlock) 
     { 
      foreach (Run run in textToInlines(textBlock.Text)) 
       textBlock.Inlines.Add(run); 
     } 

     private static IEnumerable<Run> textToInlines(string text) 
     { 
      List<Run> retval = new List<Run>(); 
      // Perform your conversion here. 
      return retval; 
     } 
    } 
} 

Si vous ajoutez une instance de cette classe à vos ressources statiques, comme ceci:

<converters:TMTInlineConverter x:Key="InlineConverter" /> 

vous pouvez alors invoquer le convertisseur de votre TextBlock comme suit:

     <TextBlock Text="{Binding MyPath}" TextWrapping="Wrap"> 
          <i:Interaction.Triggers> 
           <i:EventTrigger EventName="Loaded"> 
            <cmdex:EventToCommand Command="{Binding Source={StaticResource InlineConverter}, Path=ConvertTextToInlinesCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}" /> 
           </i:EventTrigger> 
          </i:Interaction.Triggers> 
         </TextBlock> 

Toutes mes excuses si vous n'utilisez pas MVVMLight. Si vous ne l'êtes pas, je laisserai la traduction comme un exercice pour le lecteur. :)