Loose XAML, XBAPs & Hyperlink Images

As Mark Alaczar points out in his WPF sandbox whitepaper, sandboxed top level navigation requires user initiation.

Some definitions to help this make sense:

  • Top level navigation: Navigations that target the hosting web browser. For instance, navigating the entire browser, or a specific HTML <iframe>, to http://netfx3.com.
  • User initiated: Direct result of an explicit user action. In the case of top level navigation, this is most likely the user clicking on a hyperlink. “Programmatic”, on the other hand, is the direct result of a dev action, like NavigationService.Navigate(…).

In this version of WPF, top level navigations in sandboxed apps require “user initiation.” Today, only the Hyperlink class has this notion of “user-initiatedness,” and it cannot (for security reasons) be subclassed in the internet sandbox.

There are many cases, however, where a more interesting Hyperlink than the default is desired. This post uses styling to create an image hyperlink that works in the internet sandbox.

Hyperlink is an inline-level flow content element that derives from TextElement, not ContentControl. This means it must be put inside of a text element container like Paragraph or TextBlock.

To create a more general control that can be used in different layout containers, you can use a ContentControl with the following style:

<ControlTemplate TargetType="ContentControl" x:Key="Hyperlink">
  <TextBlock Text="" TextWrapping="Wrap">
    <Hyperlink TextDecorations="" NavigateUri="http://www.netfx3.com">
      <Image Style="{StaticResource HyperlinkImage}">
      </Image>
    </Hyperlink>
  </TextBlock>
</ControlTemplate>

You can than style the image, perhaps adding a mouse over trigger:

<Style x:Key="HyperlinkImage" TargetType="{x:Type Image}">
  <Setter Property="Source">
    <Setter.Value>
      <BitmapImage UriSource="flowers_color.jpg"/>
    </Setter.Value>
  </Setter>

  <Setter Property="HorizontalAlignment" Value="center"/>
  <Setter Property="VerticalAlignment" Value="center"/>
  <Setter Property="Stretch" Value="Uniform"/>
  <Setter Property="IsEnabled" Value="true"/>

  <!-- Hover Trigger to change image source-->
  <Style.Triggers>
    <Trigger Property="Image.IsMouseOver" Value="true">
      <Setter Property="Image.Source">
        <Setter.Value>
          <BitmapImage UriSource="flowers_bw.jpg"/>
        </Setter.Value>
      </Setter>
    </Trigger>
  </Style.Triggers>
</Style>

Then create the ContentControl itself:

<WrapPanel Margin="40" Orientation="Vertical">
  <ContentControl  Width="100" Template="{StaticResource Hyperlink}"/>
</WrapPanel>

You can try it out in loose xaml here.

1 comment

  1. I am curious what people’s thoughts are with regard to XBAP and Sharepoint Web Parts.

    In an environment, where we can require that our customers run IE 7 and WPF on the client, and Sharepoint on the server, it seems like anything other XBAP is a waste of time, including Ajax, Atlas, Windows Forms, etc.

Leave a Reply

Your email address will not be published. Required fields are marked *