9

我看到了很多关于移除后台堆栈的答案。

但是如何删除前向堆栈?

又名,导航 A,到 B,到 C

A -> B -> C

然后我从 C 导航回 B(表单已保存,C 已关闭NavigationService.GoBack();

B <- C

我现在应该不能使用前进按钮导航回 C。但不知道如何实现这一点。以某种方式将其从堆栈中删除是最有意义的。

4

1 回答 1

0

我知道这个问题是很久以前发布的,但最近我偶然发现了类似的问题,这就是我为我的案例解决的方法。我希望它会帮助某人。

要求

用户应该能够返回到之前访问过的页面,但一旦按下后退按钮就不能前进。

我的方法

Frame创建一个派生自并添加两个附加 DP的自定义控件AllowForwardNavigationAllowBackNavigation以便我可以控制是否要允许上一个/下一个导航。

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" />
于 2018-08-21T18:20:07.723 回答