NavigationService删除forwardstack

时间:2016-11-16 10:12:56

标签: c# wpf navigationservice

我看到很多答案,关于拆除后台堆。

但是如何删除前向堆栈?

Aka,导航A,到B,到C

A - > B - > ç

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

B < - C

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

1 个答案:

答案 0 :(得分: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" />