ChrisF
ChrisF

Reputation: 137158

How can I delete a hyperlink in a Silverlight RichTextBox?

I have a RichTextBox that the user can edit to create a hyperlink (in my case to another page with the document rather than an external URL). Having successfully created the link I now need to be able to remove it.

I have code that identifies that I've got a hyperlink in the current selection:

TextSelection linkText = richTextBox.Selection;

if (linkText != null && !string.IsNullOrWhiteSpace(linkText.Text))
{
    XElement root = XElement.Parse(linkText.Xaml);
    XNamespace ns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
    XElement linkElement = root.Element(ns + "Paragraph").Element(ns + "Hyperlink");
    if (linkElement != null)
    {
       // Get here if have a Hyperlink. How do I remove or update?
    }
}

However, I'm now stuck on the bit that goes inside the if test. How do I find the hyperlink so I can remove it completely?

My code for setting up the hyperlink is:

TextSelection linkText = richTextBox.Selection;
var hyperlink = new Hyperlink();

hyperlink.Inlines.Add(linkText.Text);
if (!String.IsNullOrEmpty(selectedTopic))  // A string holding the link target
{
    // Setup hyperlink here
}

linkText.Insert(hyperlink);

I've managed to work out how to update the hyperlink:

foreach (var block in richTextBox.Blocks)
{
    Paragraph p = block as Paragraph;

    foreach (var inline in p.Inlines)
    {
        var hyperlink = inline as Hyperlink;
        if (hyperlink != null && hyperlink.NavigateUri.AbsoluteUri.Contains(currentLink))
        {
            hyperlink.NavigateUri = new Uri(newLink);
        }
    }
}

I could use the same approach to delete the hyperlink, but how do I convert the Hyperlink to a normal Inline?

Upvotes: 2

Views: 576

Answers (1)

AnthonyWJones
AnthonyWJones

Reputation: 189495

Looks like you are getting close you just need to hold a reference to the link then use Remove. Something like the following (I like to use Linq to make things a little more succinct):-

foreach (var p in richTextBox.Blocks.OfType<Paragraph>()) 
{ 
    var hyperlink = p.Inlines.OfType<HyperLink>()
        .FirstOrDefault(hl => hl.NavigateUri.AbsoluteUri.Contains(currentLink));

    if (hyperlink != null)
    {
         p.Inlines.Remove(hyperlink);
         break;
    }
} 

Edit: Want to leave the content of hyperlink in place? (i.e., just remove the wrapping hyperlink),

foreach (var p in richTextBox.Blocks.OfType<Paragraph>()) 
{ 
    var hyperlink = p.Inlines.OfType<HyperLink>()
        .FirstOrDefault(hl => hl.NavigateUri.AbsoluteUri.Contains(currentLink));

    if (hyperlink != null)
    {
         int index = p.Inlines.IndexOf(hyperlink);
         Span span = new Span();

         foreach (var inline in hyperlink.Inlines.ToArray())
         {
             hyperlink.Inlines.Remove(inline);
             span.Inlines.Add(inline);
         }

         // You may need code here to preserve the Font properties etc  from hyperlink to span.

         p.Inlines[index] = span;
         break;
    }
}

Upvotes: 3

Related Questions