Professional, Software

Hyperlink Control

 One of the things I needed to build for my Search application is hyperlinks. So that people can navigate to actual search results if they wanted to. Remember couple of places in my application, I display where the image came from but it is just text and user can not do anything with it. I would like it to be hyperlink and click on it and navigate to the destination. So what is the basic functionality I needed from my hyperlink.

  1. It can take the Uri where link is supposed to point to
  2. It can take text that it displays on the page
  3. It can support hyperlink targeting i.e It can navigate either iframe on a current page, or current browser window or open new browser window.
  4. It should support click tracking i.e. changing colors when user has visited this site once. I did not get time to write this one but it should be possible to do using isolated storage.
  5. It should support right click menu but can not do it till Silverlight has input support for right mouse click. 

Blank  iframe  newwindow

Code for  Hyperlink.xaml

<Canvas xmlns="http://schemas.microsoft.com/client/2007" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Width="40" 
        Height="20" Cursor="Hand" 
        > 
    <TextBlock x:Name="txtlink" Width="40" Height="20" 
             Canvas.Left="0" Canvas.Top="0" 
             FontFamily="Arial Unicode MS" FontSize="14" 
             FontWeight="Normal" Foreground="#FF3281D4" 
             Text="Test" TextWrapping="Wrap" /> 
</Canvas>

Code for Hyperlink.xaml.cs

using System; 
using System.IO; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Input; 
using System.Windows.Browser;     

namespace HyperlinkApp 
{ 
    public class Hyperlink : Control 
    { 
        private Canvas rootCanvas; 
        private TextBlock txtlink; 
        private Uri _navigateUri; 
        private string _targetname; 
        private bool click;     

        public Hyperlink() 
        { 
            Stream s = this.GetType().Assembly.GetManifestResourceStream("HyperlinkApp.Hyperlink.xaml"); 
            rootCanvas = (Canvas)this.InitializeFromXaml(new StreamReader(s).ReadToEnd()); 
            txtlink = (TextBlock) rootCanvas.FindName("txtlink"); 
            this.Loaded += new EventHandler(Hyperlink_Loaded); 
            this.MouseLeftButtonDown += new MouseEventHandler(Hyperlink_MouseLeftButtonDown); 
            this.MouseLeave += new EventHandler(Hyperlink_MouseLeave); 
            this.MouseLeftButtonUp += new MouseEventHandler(Hyperlink_MouseLeftButtonUp); 
            this.MouseEnter += new MouseEventHandler(Hyperlink_MouseEnter); 
            this.Cursor = Cursors.Hand; 
        }     

        void Hyperlink_MouseEnter(object sender, MouseEventArgs e) 
        { 
            txtlink.TextDecorations = TextDecorations.Underline; 
        }     

        void Hyperlink_MouseLeftButtonUp(object sender, MouseEventArgs e) 
        { 
            if (click == true) 
            { 
                if (_navigateUri != null) 
                { 
                    if (_targetname == null) 
                        HtmlPage.Navigate(_navigateUri.ToString()); 
                    else if(_targetname.ToLower().Equals("new") == true) 
                        HtmlPage.Navigate(_navigateUri.ToString(),"__newWindow"); 
                    else 
                        HtmlPage.Navigate(_navigateUri.ToString(), _targetname); 
                } 
            } 
        }     

        void Hyperlink_MouseLeave(object sender, EventArgs e) 
        { 
            click = false; 
            txtlink.TextDecorations = TextDecorations.None; 
        }     

        void Hyperlink_MouseLeftButtonDown(object sender, MouseEventArgs e) 
        { 
            click = true; 
        }     

        public String NavigateUri 
        { 
            get { return (_navigateUri!= null? _navigateUri.ToString():null); } 
            set 
            { 
                try 
                { 
                    _navigateUri = new Uri(value, UriKind.RelativeOrAbsolute); 
                } 
                catch (UriFormatException) 
                { 
                    _navigateUri = null; 
                } 
            } 
        }     

        public string TargetName 
        { 
            get { return _targetname; } 
            set { _targetname = value; } 
        }     

        public string Text 
        { 
            get { return txtlink.Text; } 
            set { txtlink.Text = value; } 
        }     

        //Usual Layout GOO 
        void Hyperlink_Loaded(object sender, EventArgs e) 
        { 
            UpdateLayout(); 
        }     

        private void UpdateLayout() 
        { 
            rootCanvas.Height = Height; 
            rootCanvas.Width = Width; 
            txtlink.Height = Height; 
            txtlink.Width = Width; 
        }     

        public new double Height 
        { 
            get { return ((FrameworkElement)this).Height; } 
            set 
            { 
                ((FrameworkElement)this).Height = value; 
                UpdateLayout(); 
            } 
        }     

        public new double Width 
        { 
            get { return ((FrameworkElement)this).Width; } 
            set 
            { 
                ((FrameworkElement)this).Width = value; 
                UpdateLayout(); 
            } 
        } 
    } 
} 

Ideally, I would have liked the TargetUri property to be of type Uri rather than a string but since there is no built-in type converter for Uri yet, Xaml parser would know how to set that property. That is the reason why I have that property as a string and then I internally convert it as a Uri. 

Code for Page.xaml

<Canvas x:Name="parentCanvas" 
        xmlns="http://schemas.microsoft.com/client/2007" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:mycontrol="clr-namespace:HyperlinkApp;assembly=ClientBin/HyperlinkApp.dll" 
        Loaded="Page_Loaded" 
        x:Class="HyperlinkApp.Page;assembly=ClientBin/HyperlinkApp.dll" 
        Width="640" 
        Height="480" 
        Background="White"> 
  <mycontrol:Hyperlink 
    Height="20" Width="450" 
    NavigateUri="http://www.silverlight.net" 
    TargetName="Test" 
    Text="Navigate iFrame" /> 
  <mycontrol:Hyperlink 
    Height="20" Width="450" 
    NavigateUri="http://www.silverlight.net" 
    Canvas.Top="30" 
    Text="Navigate Browser"/> 
  <mycontrol:Hyperlink 
    Height="20" Width="450" 
    NavigateUri="http://www.silverlight.net" 
    TargetName="New" 
    Canvas.Top="60" 
    Text="Navigate New Browser Window"/> 
</Canvas>

 Link to full project is here.

About these ads
Standard

One thought on “Hyperlink Control

  1. Pingback: Michael Sync » Silverlight 2.0 - How to design the blog theme with Silverlight

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s