Reputation: 3130
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
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
Reputation: 184296
TargetName
only works for windows and frames according to MSDN, so this is not possible.
Upvotes: 0