Use of hyperlinks inside text at Silverlight 3

Insert of a hyperlink in the text - absolutely usual task for web-applications. Frequently we do it when makes HTML documents. Unfortunately, default controls in Silverlight do not allow to insert a hyperlink in the text. Let's consider an example of how it is possible to bypass this restriction.

If to be fair in Silverlight 3 there is an control HyperlinkButton which all the same allows to insert hyperlinks into Silverlight applications. The problem of such control consists that by default it is impossible to insert it in the text. Construction of a new control can be one of the decision of the given problem.

First, we will split our statement into words. The blank or punctuation marks can be a divider, for example. After that it will be necessary to understand what of words should be hyperlinks. For these purposes it is possible to use regular expressions, for example.

Secondly, for each word we will create own instance of control. If the word is not a hyperlink we will create for it an control TextBlock. If the word is a hyperlink we will create for it an control HyperlinkButton.

At last, we will place all our controls in WrapPanel container.

The own control can be realised in several ways. As base it is possible to use UserControl or any other types of controls. However, it is more convenient to choose as base object WrapPanel because any additional logic in our case it is not required.

Let's consider process of construction of such control step-by-step.

1) Let's create the control and we will inherit it from WrapPanel.

public class LinkTextBlock : WrapPanel
{
//...
}

2) Let's create property which contains the text.

public class LinkTextBlock : WrapPanel
{
    public static DependencyProperty TextProperty;
 
    static LinkTextBlock()
    {
        TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(LinkTextBlock), new PropertyMetadata(String.Empty, TextChangedCallback));
 
        // ...
    }
 
    private static void TextChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = (LinkTextBlock)d;
        control.BuildControls();
    }
 
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
 
    // ...
}

3) Let's define a method for statement's splitting on words. Let's start this method every time when the text is updated (method TextChangedCallback).

private void BuildControls()
{
    Children.Clear();
 
    foreach (UIElement control in from word in Text.Split(' ')
                                  select BuildWordControl(word))
    {
        Children.Add(control);
    }
}

4) We define a method for construction of control for each word.

private UIElement BuildWordControl(string text)
{
    UIElement result;
    string url, displayText;
 
    if ((CheckLinkMethod != null) && (CheckLinkMethod(text, out url, out displayText) == true))
    {
        Uri navigateUri = new Uri(..);
 
        result = new HyperlinkButton() { Content = displayText, Tag = url, NavigateUri = navigateUri };
        ((HyperlinkButton)result).Click += delegate(object sender, RoutedEventArgs e)
                                               {
                                                    // do something
                                               };
    }
    else
    {
        result = new TextBlock() { Text = text };
    }
 
    return result;
}

Now the control is ready to the use :)

In a final code I have inserted delegates who allow to set logic of definition of hyperlinks, styles for words, tool tips and other elements. You can download source code by using following link.

No Comments