Использование кнопки для перехода на другую страницу в окне навигации
-
03-07-2019 - |
Вопрос
Я пытаюсь использовать структуру команд навигации в WPF для навигации между страницами в приложении WPF (рабочий стол;не XBAP или Silverlight).
Я считаю, что у меня все настроено правильно, но это не работает.Я создаю и запускаю без ошибок, я не получаю никаких ошибок привязки в окне вывода, но моя кнопка навигации отключена.
Вот app.xaml для примера приложения:
<Application x:Class="Navigation.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="First.xaml">
</Application>
Обратите внимание, что StartupUri указывает на First.xaml.Во-первых,xaml - это страница.WPF автоматически размещает мою страницу в окне навигации.Вот First.xaml:
<Page x:Class="Navigation.First"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="First">
<Grid>
<Button
CommandParameter="/Second.xaml"
CommandTarget="{Binding RelativeSource=
{RelativeSource
FindAncestor,
AncestorType={x:Type NavigationWindow}}}"
Command="NavigationCommands.GoToPage"
Content="Go!"/>
</Grid>
</Page>
Для параметра CommandTarget кнопки установлено значение NavigationWindow.Команда называется GoToPage, а страница - /Second.xaml.Я попытался установить CommandTarget на содержащую страницу, CommandParameter на "Second.xaml" (First.xaml и Second.xaml находятся в корневом каталоге решения), и я попытался оставить CommandTarget пустым.Я также попытался установить Путь к привязке к различным общедоступным свойствам, связанным с навигацией, в NavigationWindow.До сих пор ничего не получалось.
Чего я здесь не понимаю?Я в самом деле не хочу делать свою навигацию в коде.
Разъяснение.
Если вместо кнопки я использую гиперссылку:
<Grid>
<TextBlock>
<Hyperlink
NavigateUri="Second.xaml">Go!
</Hyperlink>
</TextBlock>
</Grid>
все работает, как и ожидалось.Однако мои требования к пользовательскому интерфейсу означают, что использование гиперссылки недопустимо.Мне нужна большая жирная кнопка, на которую люди могли бы нажимать.Вот почему я хочу использовать кнопку для навигации.Я просто хочу знать, как я могу заставить Кнопку предоставлять ту же возможность, что и Гиперссылка в данном случае.
Решение
В соответствии с Документация, только DocumentViewer
и FlowDocumentViewer
реализуйте эту команду специально.Вам нужно будет либо найти команду для навигации, которая NavigationWindow
реализует или настраивает CommandBinding
выполните эту команду и обработайте ее самостоятельно.
Другие советы
В XAML:
<Button Command="{x:Static Views:Commands.NavigateHelp}" Content="Help"/>
В представлениях (у нас есть Commands.cs
файл, содержащий все это):
public static RoutedCommand NavigateHelp = new RoutedCommand();
В конструкторе страницы вы можете соединить эти два:
CommandBindings.Add(new CommandBinding(Commands.NavigateHelp, NavigateHelpExecute));
NavigateHelpExecute может быть в коде (что мы и делаем), подключаться к обработчику событий ViewModel или к чему-то еще.Прелесть этого в том, что вы можете отключить другую навигацию следующим образом:
CommandBindings.Add(new CommandBinding(NavigationCommands.Refresh, null));
Надеюсь, это поможет.
Вы захотите использовать NavigationService
из вашего NavigationWindow
следующим образом:
XAML:
<Button HorizontalAlignment="Right" Name="continueButton" Width="75" Margin="0,0,8,11" Height="23" VerticalAlignment="Bottom" Click="continueButton_Click">
Continue
</Button>
C#:
private void continueButton_Click(object sender, RoutedEventArgs e)
{
this.NavigationService.GoForward();
//or
this.NavigationService.Navigate("Second.xaml")
}
С любым из этих способов вы можете использовать use this
, я только показываю NavigationService
здесь для ясности
public class NavigateButton : Button
{
public Uri NavigateUri { get; set; }
public NavigateButton()
{
Click += NavigateButton_Click;
}
void NavigateButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
var navigationService = NavigationService.GetNavigationService(this);
if (navigationService != null)
navigationService.Navigate(NavigateUri);
}
}
И тогда вы можете поместить следующее в свой xaml:
<local:NavigateButton Content="NavigateButton" NavigateUri="Page2.xaml"/>
Тогда вам по-прежнему не нужен код за вашими страницами, и вам не нужно добавлять команды в вашу viewmodel.