NavigationService удалить форвардстак
Я вижу много ответов о снятии backstack.
Но как мне удалить стек вперед?
Ака, Навигация A, к B, к C
A -> B -> C
Затем я возвращаюсь из C в B (Форма сохранена, C закрыта NavigationService.GoBack();
)
B <- C
Теперь я НЕ должен быть в состоянии вернуться назад к C, используя кнопку вперед. Но понятия не имею, как это реализовать. Наиболее разумно как-то удалить его из стека.
1 ответ
Я знаю, что этот вопрос был опубликован давно, но недавно я наткнулся на похожую проблему, и именно так я решил ее для своего случая. Надеюсь, это кому-нибудь поможет.
требование
Пользователь должен иметь возможность вернуться на ранее посещенные страницы, но не должен быть в состоянии перейти вперед после нажатия кнопки "Назад".
Мой подход
Создать пользовательский элемент управления, полученный из Frame
и добавить два дополнительных DP AllowForwardNavigation
а также AllowBackNavigation
так что я могу контролировать, если я хочу, чтобы предыдущая / следующая навигация.
MyFrame.xaml.cs
public partial class MyFrame : Frame
{
#region Dependency Properties
public bool AllowForwardNavigation
{
get { return (bool)GetValue(AllowForwardNavigationProperty); }
set { SetValue(AllowForwardNavigationProperty, value); }
}
public static readonly DependencyProperty AllowForwardNavigationProperty =
DependencyProperty.Register(nameof(AllowForwardNavigation), typeof(bool), typeof(MyFrame), new PropertyMetadata(true));
public bool AllowBackNavigation
{
get { return (bool)GetValue(AllowBackNavigationProperty); }
set { SetValue(AllowBackNavigationProperty, value); }
}
public static readonly DependencyProperty AllowBackNavigationProperty =
DependencyProperty.Register(nameof(AllowBackNavigation), typeof(bool), typeof(MyFrame), new PropertyMetadata(true));
#endregion
public MyFrame()
{
InitializeComponent();
JournalOwnership = JournalOwnership.OwnsJournal;
// find existing bindings
var existingBindings = CommandBindings.OfType<CommandBinding>()
.Where(x => x.Command == NavigationCommands.BrowseForward
|| x.Command == NavigationCommands.BrowseBack)
.ToArray();
// remove existing bindings
foreach (var binding in existingBindings)
CommandBindings.Remove(binding);
// add new binding
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseForward, OnGoForward, OnQueryGoForward));
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseBack, OnGoBack, OnQueryGoBack));
// override default navigation behavior
NavigationService.Navigating += NavigationService_Navigating;
}
private void NavigationService_Navigating(Object sender, NavigatingCancelEventArgs e)
{
switch (e.NavigationMode)
{
case NavigationMode.Forward:
e.Cancel = !AllowForwardNavigation;
break;
case NavigationMode.Back:
e.Cancel = !AllowBackNavigation;
break;
}
}
#region Command methods
private void OnGoForward(Object sender, ExecutedRoutedEventArgs e)
{
e.Handled = true;
if (AllowForwardNavigation && NavigationService.CanGoForward)
NavigationService.GoForward();
}
private void OnQueryGoForward(Object sender, CanExecuteRoutedEventArgs e)
{
e.Handled = true;
e.CanExecute = AllowForwardNavigation && NavigationService.CanGoForward;
}
private void OnGoBack(Object sender, ExecutedRoutedEventArgs e)
{
e.Handled = true;
if (AllowBackNavigation && NavigationService.CanGoBack)
NavigationService.GoBack();
}
private void OnQueryGoBack(Object sender, CanExecuteRoutedEventArgs e)
{
e.Handled = true;
e.CanExecute = AllowBackNavigation && NavigationService.CanGoBack;
}
#endregion
}
MyFrame.xaml
<Style x:Key="NavigationWindowBackButtonStyle" TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Command" Value="NavigationCommands.BrowseBack"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Background="Transparent" Height="24" Width="24">
<Ellipse x:Name="Circle" Fill="{StaticResource NavigationWindowNavigationButtonFillEnabled}" Stroke="{StaticResource NavigationWindowNavigationButtonStrokeEnabled}" StrokeThickness="1"/>
<Path x:Name="Arrow" Data="M0.37,7.69 L5.74,14.20 A1.5,1.5,0,1,0,10.26,12.27 L8.42,10.42 14.90,10.39 A1.5,1.5,0,1,0,14.92,5.87 L8.44,5.90 10.31,4.03 A1.5,1.5,0,1,0,5.79,1.77 z" Fill="{StaticResource NavigationWindowNavigationArrowFill}" HorizontalAlignment="Center" Stroke="{StaticResource NavigationWindowNavigationArrowStrokeEnabled}" StrokeThickness="0.75" VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="Circle" Value="{StaticResource NavigationWindowNavigationButtonFillDisabled}"/>
<Setter Property="Stroke" TargetName="Circle" Value="#B5BACE"/>
<Setter Property="Stroke" TargetName="Arrow" Value="#B0B5BACE"/>
<Setter Property="Fill" TargetName="Arrow" Value="#D0FFFFFF"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="Circle" Value="{StaticResource NavigationWindowNavigationButtonFillHover}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Fill" TargetName="Circle" Value="{StaticResource NavigationWindowNavigationButtonFillPressed}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="NavigationWindowForwardButtonStyle" TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Command" Value="NavigationCommands.BrowseForward"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Background="Transparent" Height="24" Width="24">
<Ellipse x:Name="Circle" Grid.Column="0" Fill="{StaticResource NavigationWindowNavigationButtonFillEnabled}" Stroke="{StaticResource NavigationWindowNavigationButtonStrokeEnabled}" StrokeThickness="1"/>
<Path x:Name="Arrow" Grid.Column="0" Data="M0.37,7.69 L5.74,14.20 A1.5,1.5,0,1,0,10.26,12.27 L8.42,10.42 14.90,10.39 A1.5,1.5,0,1,0,14.92,5.87 L8.44,5.90 10.31,4.03 A1.5,1.5,0,1,0,5.79,1.77 z" Fill="{StaticResource NavigationWindowNavigationArrowFill}" HorizontalAlignment="Center" RenderTransformOrigin="0.5,0" Stroke="{StaticResource NavigationWindowNavigationArrowStrokeEnabled}" StrokeThickness="0.75" VerticalAlignment="Center">
<Path.RenderTransform>
<ScaleTransform ScaleX="-1"/>
</Path.RenderTransform>
</Path>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="Circle" Value="{StaticResource NavigationWindowNavigationButtonFillDisabled}"/>
<Setter Property="Stroke" TargetName="Circle" Value="#B5BACE"/>
<Setter Property="Stroke" TargetName="Arrow" Value="#B0B5BACE"/>
<Setter Property="Fill" TargetName="Arrow" Value="#D0FFFFFF"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="Circle" Value="{StaticResource NavigationWindowNavigationButtonFillHover}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Fill" TargetName="Circle" Value="{StaticResource NavigationWindowNavigationButtonFillPressed}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Frame.Resources>
<Frame.Template>
<ControlTemplate TargetType="Frame">
<DockPanel Margin="7">
<StackPanel Visibility="{TemplateBinding NavigationUIVisibility}" Margin="0" Orientation="Horizontal"
DockPanel.Dock="Top">
<Button Style="{StaticResource NavigationWindowBackButtonStyle}"
Command="NavigationCommands.BrowseBack"
Content="M 4 0 L 0 4 L 4 8 Z"
Margin="2.7,0,1.3,0" />
<Button Style="{StaticResource NavigationWindowForwardButtonStyle}"
Command="NavigationCommands.BrowseForward"
Content="M 4 0 L 0 4 L 4 8 Z" Margin="1.3,0,0,0" />
</StackPanel>
<Border>
<ContentPresenter />
</Border>
</DockPanel>
</ControlTemplate>
</Frame.Template>
</Frame>
использование
<local:MyFrame x:Name="_mainFrame" NavigationUIVisibility="Visible"
AllowForwardNavigation="False" />