Динамическое пользовательское содержимое в RichTextBox

#c# #data-binding #silverlight-4.0 #richtextbox

#c# #привязка к данным #silverlight-4.0 #richtextbox

Вопрос:

Я хочу отобразить текст гиперссылки в RichTextBox из исходного кода или привязанного через Xaml, если есть такая возможность.

На данный момент у меня есть строковая переменная с URL-адресом (который я бы очень хотел сделать интерактивным), привязанным к текстовому блоку. Я бы хотел в основном заменить:

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

с помощью (в richTB:)

 <Run Text="partOfTextNonUrl" /><Hyperlink NavigateUri="theUrl" TargetName="whatever" />
  

Вот как это представлено:

У меня есть шаблон ItemsControl с пользовательским объектом

 <ItemsControl ItemsSource="{Binding FeedResults}">
 <ItemsControl.ItemTemplate>
  <DataTemplate>
   <StackPanel Orientation="Vertical" >
    <my:SearchResultItem />
   </StackPanel>
  </DataTemplate>
 </ItemsControl.ItemTemplate>
</ItemsControl>
  

И этот пользовательский элемент управления представляет привязанные данные в 3 текстовых блоках, как показано выше: заголовок, дата и текст, содержащий текст URL-адреса.

У меня уже есть метод, который извлекает URL-адреса из строки, я просто не знаю, как его использовать. Я могу генерировать динамически Run() и Hyperlink() и добавлять их в абзац, но как привязать?

Или любое другое решение? Вы бы сделали мой день!!

Спасибо, Сильвен

Ответ №1:

ОК. Так что, по-видимому, встроенные гиперссылки даже не разрешены в Silverlight. Но вы можете создать свой собственный!

http://csharperimage.jeremylikness.com/2009/11/inline-hyperlinks-in-silverlight-3.html

Непросто — по крайней мере, не так просто, как должно быть. Но он должен выполнить свою работу.

Как только у вас появится возможность добавлять эти прогоны с гиперссылками, я бы подошел к этому следующим образом. Создайте пользовательский элемент управления с помощью одного TextBlock ( txtContent ). Установите DataContext="{Binding myTextWithUrl}" . Затем в коде, лежащем в основе:

 public TextWithUrlUserControl()
{
    InitializeComponent();

    this.Loaded  = (s, e) =>
                        {
                            foreach(var inline in ParseText(DataContext as string))
                                txtContent.Inlines.Add(inline);
                        };
} 

IEnumerable<Inline> ParseText(string text)
{
    // return list of Runs and Runs with hyperlinks using your URL parsing
    // for demo purposes, just hardcoding it here:
    return new List<Inline>
                {
                    new Run{Text="This text has a "},
                    new Run{Text="URL", RunExtender.NavigateUrl="http://www.google.com/"},
                    new Run{Text="in it!"}
                };    
}
  

Надеюсь, это полезно.

Комментарии:

1. Привет, Адам, это действительно работает, однако я пришел с другим решением благодаря сообщению Adams Sills ( blogs.catapultsystems.com/asills/archive/2010/11/17 /… ) и я мог бы привязать свойство Xaml. Вот что я сделал: mysharpsnippets.wordpress.com/2011/11/06/… Еще раз спасибо за вашу помощь 😉

Ответ №2:

Я бы сделал что-то вроде этого. Создайте ValueConverter, который будет принимать ваш текст (с URL-адресом в нем). Затем в вашем текстовом блоке создайте Run и гиперссылку — привяжите оба к тексту, оба с использованием ValueConverter, но с параметром, отличным от ValueConverter .

Преобразователь значений:

 public class MyCustomValueConverter: IValueConverter
{    
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if(parameter.ToString()== "URL")
        {
            // return the URL part of the string
        }
        else
        {
            // return the non-URL portion of the string
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
  

Тогда ваш XAML выглядит следующим образом:

 <Run Text="{Binding myTextWithUrl, Converter={StaticResource valueConverter}}"></Run><Hyperlink NavigateUri="{Binding myTextWithUrl, Converter={StaticResource valueConverter}, ConverterParameter=URL}"></Hyperlink>
  

Комментарии:

1. Спасибо, Адам, это сработало бы, если бы я знал, что у меня есть текст гиперссылка, хитрость в том, что я не знаю, есть ли у меня URL или несколько в тексте. Например, у меня может быть none или 3. Итак, мне нужно каким-то образом динамически генерировать запуск и гиперссылку.

2. Ах. Понял. Я скоро добавлю еще один ответ, представляющий, как я, вероятно, подхожу к этому…