NavigationService 删除 forwardstack

Posted

技术标签:

【中文标题】NavigationService 删除 forwardstack【英文标题】:NavigationService remove forwardstack 【发布时间】:2017-03-30 11:44:26 【问题描述】:

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

但是如何移除前向堆栈?

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

A -> B -> C

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

B

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

【问题讨论】:

有谁知道如何做到这一点?还在苦苦挣扎。 只是一个想法——当你在 B 并且你不知何故知道你从 C 回来时,重复导航到 B。这应该使 B 成为最近访问的元素,所以没有办法去 C。再一次,只是一个想法 - 没有尝试过。 @AlexSeleznyov 感谢您的建议。我检查了CanGoForward 是否然后导航到其自身的副本(B2),并删除后台堆栈以删除原始 B。这似乎是一个 hacky 实现。因为它本质上必须重新加载 B。但无论如何我都在重新加载页面上的数据所以不是一个巨大的打击。这是一个解决方案,但想知道是否有更好的解决方案。至少很高兴它的工作。谢谢! 您可能还想深入研究 NavigationService 代码 - 我记得有一个依赖属性 CanGoForward 和一些围绕其状态的逻辑,因此可能值得尝试将该属性直接设置为 false。又是一个想法。 你看到这个问题了吗:***.com/q/1908675/656243 .. 它似乎正是你要找的。​​span> 【参考方案1】:

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

要求

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

我的方法

创建一个从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" />

【讨论】:

以上是关于NavigationService 删除 forwardstack的主要内容,如果未能解决你的问题,请参考以下文章

WPF:第二次页面访问后 NavigationService 为 NULL

typescript IF_05_06_NavigationService_TS

html IF_05_08_NavigationService_Office_HTML

typescript IF_05_09_NavigationService_Office_TS

typescript IF_05_07_NavigationService_Home_TS

NavigationService.Navigate(Uri())带参数传值初始化