简体   繁体   中英

Dynamic custom content in RichTextBox

I wish to display a text + hyperlinks in a RichTextBox from the code-behind or the binded via the Xaml if there is the possibility.

For the moment, I have a string variable with a Url (that I'd like very much to make clickable) binded to a TextBlock. I'd like to basically replace:

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

by (in a richTB: )

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

Here is how it is presented:

I have an ItemsControl templated with a custom object

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

And this custom control presents the binded data in 3 TextBlocks as presented above: title, date, and the text containing text + urls.

I have already a method that extracts the urls from the string, I just don't know how to use it. I can generate dynamically Run() and Hyperlink(), and add them to the paragraph, but how to bind ?

Or any other solution ? You'd make my day!!

Thanks, Sylvain

I would do something like this. Create a ValueConverter which will take your text (with the URL in it). Then in your TextBlock, create the Run and Hyperlink - bind both to the text, both using the ValueConverter, but with a different parameter to the ValueConverter.

The 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();
    }
}

Then your XAML looks like this:

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

OK. So apparently inline Hyperlinks aren't even allowed in Silverlight. But you can make your own!

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

Not easy - at least not as easy at it should be. But it should get the job done.

Once you have the ability to add these runs with hyperlinks, the way I'd approach it is this. Create a user control with a single TextBlock ( txtContent ). Set the DataContext="{Binding myTextWithUrl}" . Then in the code behind:

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

Hope this is helpful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM