SaphuA
SaphuA

Reputation: 3130

TextBlock HyperLink and Anchor?

I have a simple TextBlock like this (it has to be a TextBlock):

<ScrollViewer Height="50" VerticalAlignment="Top">
<TextBlock>
    <Hyperlink TargetName="TestAnchor">Test</Hyperlink><LineBreak />
    <TextBlock Text="Line" /><LineBreak />
    <TextBlock Text="Line" /><LineBreak />
    <TextBlock Text="Line" /><LineBreak />
    <TextBlock Text="Line" /><LineBreak />
    <TextBlock Text="Line" /><LineBreak />
    <TextBlock Text="Line" /><LineBreak />
    <TextBlock Text="Line" /><LineBreak />
    <TextBlock Text="Line" /><LineBreak />
    <TextBlock Text="Line" /><LineBreak />
    <TextBlock Text="Line" /><LineBreak />
    <TextBlock Text="Line" /><LineBreak />
    <TextBlock Text="Line" /><LineBreak />
    <Hyperlink Name="TestAnchor" />
</TextBlock>
</ScrollViewer>

What I would like to do is when the user clicks the HyperLink on top, that it will scroll down the Anchor on the bottom. Is this even possible in WPF?

Thanks!

Upvotes: 1

Views: 2154

Answers (2)

Snowbear
Snowbear

Reputation: 17274

You can use BringIntoView method which should scroll your scrollViewer to the FrameworkElement on which you invoked BringIntoView. The next step is to match clicked hyperlink with target hyperlink. Most straightforward approach would be using a Dictionary. And last step would be to handle Hyperlink.Click event.

Code behind:

private readonly Dictionary<Hyperlink,FrameworkElement> HyperlinkTargets = 
                    new Dictionary<Hyperlink,FrameworkElement>();

public Constructor()
{
    InitializeComponent();
    HyperlinkTargets.Add(TestHyperlink, TestAnchor);
}

// this event handler should be attached to hyperlinks which will be used for navigation
private void Hyperlink_Click(object sender, RoutedEventArgs e)
{
    var clickedHyperlink = (Hyperlink)sender;
    var targetHyperlink = HyperlinkTargets[clickedHyperlink];
    targetHyperlink.BringIntoView();
}

This is basically an implementation of H.B.'s idea from his comment.


Another solution which just come to my mind. If you want to move more code into XAML you can create a command which will navigate to element passed as parameter. Here is a command class:

class NavigateToCommand : ICommand
{
    public void Execute(object parameter)
    {
        ((FrameworkElement)parameter).BringIntoView();
    }

    public bool CanExecute(object parameter)
    {
        return parameter is FrameworkElement;
    }

    public event EventHandler CanExecuteChanged;
}

And you can use it in your sample like this:

<ScrollViewer Height="50" VerticalAlignment="Top">
<ScrollViewer.Resources>
     <local:NavigateToCommand x:Key="navigateToCommand" />
</ScrollViewer.Resources>
<TextBlock>
    <Hyperlink Command="{StaticResource navigateToCommand}"
               CommandParameter="{Binding ElementName=TestAnchor}">Test</Hyperlink><LineBreak />
    /* TextBlocks */
    <Hyperlink Name="TestAnchor" />
</TextBlock>
</ScrollViewer>   

This will allow you to have everything (except new ICommand class) in XAML

Upvotes: 2

brunnerh
brunnerh

Reputation: 184296

TargetName only works for windows and frames according to MSDN, so this is not possible.

Upvotes: 0

Related Questions