Расширенное форматирование текста в TextBlock с использованием только DataBinding в XAML

Я пытаюсь отформатировать твит с помощью привязки данных. Что мне нужно сделать, так это разделить значение Text твита в зависимости от типа контента.

text = "This is a Tweet with a hyperlink http://www.mysite.com"

Мне нужно добавить цветовое форматирование в часть http://... текстового значения.

Вот в чем проблема: я бы хотел сделать это, используя только привязку данных 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}" />

// должно получиться что-то вроде

<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>

Вот регулярное выражение, которое я мог бы использовать для разделения текстового значения, но я пытаюсь использовать строго DataBinding.

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

Предложения?


person discorax    schedule 22.10.2010    source источник


Ответы (2)


Я использую MVVMLight. Что я сделал, так это перехватил событие Loaded TextBlock и перенаправил его на «конвертер».

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

Если вы добавите экземпляр этого класса в свои статические ресурсы, например:

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

затем вы можете вызвать конвертер из своего TextBlock следующим образом:

                        <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>

Приносим извинения, если вы не используете MVVMLight. Если нет, я оставлю перевод в качестве упражнения для читателя. :)

person Rob    schedule 05.02.2011

Вы не можете привязаться к Text и заменить на Runs, потому что Text имеет тип String. Вместо этого вам нужно связать Inlines и предоставить преобразователь, который анализирует текст (например, с помощью вашего регулярного выражения) и создает соответствующий Inlines:

<TextBlock Inlines="{Binding XPath=/statuses/status[2]/text, Converter={StaticResource InlineConverter}}"/>
person Kent Boogaart    schedule 22.10.2010
comment
Это то, что я понял. Спасибо за подтверждение. Я опубликую свой конвертер, когда закончу его сборку. - person discorax; 23.10.2010
comment
Вы не можете привязываться к Inlines. Свойство Inlines доступно только для чтения и не может быть установлено с помощью разметки. Есть другие предложения? - person discorax; 23.10.2010
comment
Ваше решение не сработает, но оно привело меня к этому ответу, который я сейчас пытаюсь проработать. stackoverflow.com/questions/1959856/ - person discorax; 25.10.2010