Custom Hyperlink Control for Windows(Windows 8.1, Windows Phone 8.1)

Ended up building a user control which behaves similarly in both Windows and Windows Phone environments. With this you’ll get the underline effect, stating of default color as well as the press color.
Designer code


<UserControl x:Class="MyApp.Architecture.Controls.CustomHyperlink" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MyApp.Architecture.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Background="YellowGreen">
    <HyperlinkButton x:Name="innerHyperlinkCtrl" FontFamily="Segoe WP Light">
        <HyperlinkButton.Content>
            <TextBlock FontFamily="Segoe UI" x:Name="inlineText">
					<Underline>
						<Run x:Name="ulRHlink"/>
					</Underline>
            </TextBlock>
        </HyperlinkButton.Content>
    </HyperlinkButton>
</UserControl>

C# code


public sealed partial class CustomHyperlink : UserControl
{
	private HyperlinkButton innerCtrl;
	private TextWrapping textWrapping = TextWrapping.WrapWholeWords;

	#region Constructors

	public CustomHyperlink()
	{
		this.InitializeComponent();
		this.Loaded += CustomHyperlink_Loaded;
		this.InnerCtrl = innerHyperlinkCtrl;

		this.DefaultColor = "#000000";
		this.PressedColor = "#40ff00";
	}

	#endregion

	#region Getters, Setters

	public HyperlinkButton InnerCtrl
	{
		get { return this.innerCtrl; }
		private set { this.innerCtrl = value; }
	}

	#endregion

	#region Events

	void CustomHyperlink_Loaded(object sender, RoutedEventArgs e)
	{
		this.InnerCtrl.Style = (this.Style == null) ? GetDefaultStyle() : this.Style;
		this.inlineText.TextWrapping = this.textWrapping;

		this.InnerCtrl.VerticalAlignment = this.VerticalAlignment;
		this.InnerCtrl.HorizontalAlignment = this.HorizontalAlignment;
		this.InnerCtrl.FontSize = this.FontSize;
		this.InnerCtrl.FontWeight = this.FontWeight;
		this.InnerCtrl.Margin = this.Margin;
	}

	#endregion

	#region Dependency Properties

	public static readonly DependencyProperty LinkTextProperty = DependencyProperty.Register("LinkText", typeof(string), typeof(CustomHyperlink), new PropertyMetadata(null, new PropertyChangedCallback(OnContentChanged)));
	public string LinkText
	{
		get { return (string)GetValue(LinkTextProperty); }
		set { SetValue(LinkTextProperty, value); }
	}

	private static void OnContentChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
	{
		CustomHyperlink mhl = sender as CustomHyperlink;
		mhl.ulRHlink.Text = (e.NewValue != null) ? e.NewValue.ToString() : string.Empty;
	}

	public static readonly DependencyProperty TextWrappingProperty = DependencyProperty.Register("TextWrapping", typeof(TextWrapping), typeof(CustomHyperlink), null);
	public TextWrapping TextWrapping
	{
		get { return (TextWrapping)GetValue(TextWrappingProperty); }
		set 
		{ 
			SetValue(TextWrappingProperty, value);
			this.inlineText.TextWrapping = value;
		}
	}

	public static readonly DependencyProperty DefaultColorProperty = DependencyProperty.Register("DefaultColor", typeof(string), typeof(CustomHyperlink), null);
	public string DefaultColor
	{
		get { return (string)GetValue(DefaultColorProperty); }
		set { SetValue(DefaultColorProperty, value); }
	}

	public static readonly DependencyProperty PressedColorColorProperty = DependencyProperty.Register("PressedColor", typeof(string), typeof(CustomHyperlink), null);
	public string PressedColor
	{
		get { return (string)GetValue(PressedColorColorProperty); }
		set { SetValue(PressedColorColorProperty, value); }
	}

	public static readonly DependencyProperty NavigateUriProperty = DependencyProperty.Register("NavigateUri", typeof(Uri), typeof(CustomHyperlink), null);
	public Uri NavigateUri
	{
		get { return (Uri)GetValue(NavigateUriProperty); }
		set 
		{ 
			SetValue(NavigateUriProperty, value); 
			this.InnerCtrl.NavigateUri = value; 
		}
	}

	#endregion

	#region Default Style

	private Style GetDefaultStyle()
	{
		StringBuilder styleBuilder = new StringBuilder();
		styleBuilder.Append("<Style xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" 
                      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" x:Key=\"CustomHyperlinkButtonStyle\" TargetType=\"HyperlinkButton\">");           
			styleBuilder.Append("<Setter Property=\"Template\">");
				styleBuilder.Append("<Setter.Value>");
					styleBuilder.Append("<ControlTemplate TargetType=\"HyperlinkButton\">");
						styleBuilder.Append("<Grid>");
						styleBuilder.Append("<VisualStateManager.VisualStateGroups>");
							styleBuilder.Append("<VisualStateGroup x:Name=\"CommonStates\">");
								styleBuilder.Append("<VisualState x:Name=\"Normal\">");
									styleBuilder.Append("<Storyboard x:Name=\"HyperLinkSBNormal\">");
										styleBuilder.Append("<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Foreground\" Storyboard.TargetName=\"ContentPresenter\">");
											styleBuilder.Append("<DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"" + DefaultColor + "\"/>");
										styleBuilder.Append("</ObjectAnimationUsingKeyFrames>");
									styleBuilder.Append("</Storyboard>");
								styleBuilder.Append("</VisualState>");
								styleBuilder.Append("<VisualState x:Name=\"Pressed\">");
									styleBuilder.Append("<Storyboard x:Name=\"HyperLinkSBPressed\">");
										styleBuilder.Append("<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Foreground\" Storyboard.TargetName=\"ContentPresenter\">");
											styleBuilder.Append("<DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"" + PressedColor + "\"/>");
										styleBuilder.Append("</ObjectAnimationUsingKeyFrames>");
									styleBuilder.Append("</Storyboard>");
								styleBuilder.Append("</VisualState>");
								styleBuilder.Append("<VisualState x:Name=\"Disabled\">");
									styleBuilder.Append("<Storyboard x:Name=\"HyperLinkSBDisabled\">");
										styleBuilder.Append("<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Foreground\" Storyboard.TargetName=\"ContentPresenter\">");
											styleBuilder.Append("<DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"{ThemeResource HyperlinkDisabledThemeBrush}\"/>");
										styleBuilder.Append("</ObjectAnimationUsingKeyFrames>");
									styleBuilder.Append("</Storyboard>");
								styleBuilder.Append("</VisualState>");
							styleBuilder.Append("</VisualStateGroup>");
						styleBuilder.Append("</VisualStateManager.VisualStateGroups>");
						styleBuilder.Append("<ContentPresenter x:Name=\"ContentPresenter\" AutomationProperties.AccessibilityView=\"Raw\" ContentTemplate=\"{TemplateBinding ContentTemplate}\" ContentTransitions=\"{TemplateBinding ContentTransitions}\" Content=\"{TemplateBinding Content}\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\">");
						styleBuilder.Append("</ContentPresenter>");
						styleBuilder.Append("</Grid>");
					styleBuilder.Append("</ControlTemplate>");
				styleBuilder.Append("</Setter.Value>");
			styleBuilder.Append("</Setter>");
		styleBuilder.Append("</Style>");

		return (Style)XamlReader.Load(styleBuilder.ToString());
	}

	#endregion
}

Typical Usage (XAML)


<custctrl:CustomHyperlink x:Name="GoogleLink" HorizontalAlignment="Stretch" VerticalAlignment="Center" FontSize="14" Margin="0,20,0,0" NavigateUri="www.google.com" LinkText="Link to Google"/>

Typical Usage(C# class)


CustomHyperlink customHyperlink = new CustomHyperlink();
customHyperlink.Name = standardControlName;
customHyperlink.DefaultColor = "#000000";
customHyperlink.PressedColor = "#40ff00";
customHyperlink.HorizontalAlignment = HorizontalAlignment.Left;
customHyperlink.VerticalAlignment = VerticalAlignment.Center;
customHyperlink.LinkText = "Hello There";

Happy coding…. 🙂

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s