Reputation: 1679
I am currently trying to make a "jump to" menu in my app. The way I would like it to look and work is such as one at Google design book here at the top, where you have the subtitles of every part of that page in a menu (to be precise, that navigation part with such links as Contents, Baseline Grids, Keylines and Spacing etc.). I'd like it to work without splitting it into new MVVM Views if possible, all inside one UserControl. Is it possible to create some keywords and just make a menu with "goto" links like in HTML?
<a href="#metrics-and-keylines-baseline-grids">Baseline Grids</a>
Maybe a custom ScrollViewer? But how would one know the height of every element in the UI?
Upvotes: 2
Views: 207
Reputation: 1679
Now (with great help of Michael G) I have the answer.
First of all make an ihnerited panel for the menu (for me it was parent ItemsControl
with StackPanel
host). Than subscribe to all Click events of the Button Items inside ItemsControl
. As a CommandParameter
bind to an element you want to jump to:
<Button CommandParameter="{Binding ElementName=jumpTarget}"/>
And in the Click event handler you use a solution presented here where istead of
Control_GotFocus(object sender, RoutedEventArgs e)
you pass the CommandParameter
like here:
Control_GotFocus(FrameworkElement targetControl)
You also have to get the parent ScrollViewer
and put it as AssociatedObject
in the example above (here is explained how to get parent of selected type). Of course you can avoid an event subsciption by simply using a command with parameter added to every Button
from the ItemsControl
.
Upvotes: 0
Reputation: 6745
Every framework element has a BringIntoView method. You can define a hyperlink, or button, menu, whatever that is able to invoke a command. The command would take an element as a parameter, and the command execution would call BringIntoView();
A simple example:
public class JumpToElementCommand : ICommand
{
public void Execute(object parameter)
{
FrameworkElement frameworkElement = parameter as FrameworkElement;
if (frameworkElement != null)
{
frameworkElement.BringIntoView();
}
}
public bool CanExecute(object parameter)
{
return parameter is FrameworkElement;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
Xaml Usage:
<Window.Resources>
<commands:JumpToElementCommand x:Key="JumpToElementCommand" />
</Window.Resources>
<Button Command="{StaticResource JumpToElementCommand}" CommandParameter="{Binding ElementName=FirstJump}" />
<Grid x:Name="FirstJump">
</Grid>
Edit: Added CommandManager.RequerySuggested so that the command parameter is reevaluated after loading.
Upvotes: 2