到新页面的导航将删除backstack

本文关键字:删除 backstack 导航 新页面 | 更新日期: 2023-09-27 18:17:18

我有一个奇怪的问题反复出现。有时它消失了,有时又回来了。我不能精确地指出所有的问题,我所有的断点似乎都按预期的顺序被击中了。

当我导航到一个新页面时,我的backstack一直被删除,所以按back只是背景应用程序。显然这是一个问题。

我认为这可能是我更复杂的页面和视图模型结构的结果。我为Pages的所有NavigationHelper内容创建了一个新类,强制所有的Pages子类都来自这个新类。我强制所有的页面附加到一个基本的PageViewModel类来解决两者之间的通信(我有一个更好的方法,但Xaml不玩得好),我使用NavigationService导航,在那里我调用CurrentFrame,这是return Windows.Current.Content as Frame的静态方法。

以下是我认为相关的代码。什么好主意吗?提前谢谢你了。我不知道发生了什么:/

我使用NavigationService中的导航方法(不是其他两个)向前导航,但是我的后退按钮不能正确返回。


public abstract class BaseViewModelPage : Page
{
    protected readonly NavigationHelper NavigationHelper;
    protected BaseViewModelPage()
    {
        NavigationHelper = new NavigationHelper(this);
        NavigationHelper.LoadState += navigationHelper_LoadState;
        NavigationHelper.SaveState += navigationHelper_SaveState;
        this.NavigationCacheMode = NavigationCacheMode.Required;
    }
    protected BasePageViewModel CurrentPageViewModel
    {
        get { return DataContext as BasePageViewModel; }
    }
    #region Navigation Registration
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        NavigationHelper.OnNavigatedTo(e);
    }
    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        NavigationHelper.OnNavigatedFrom(e);
    }
    protected virtual void LoadState(LoadStateEventArgs e)
    {
        if (CurrentPageViewModel != null)
        {
            CurrentPageViewModel.LoadState(e);
        }
    }
    protected virtual void SaveState(SaveStateEventArgs e)
    {
        if (CurrentPageViewModel != null)
        {
            CurrentPageViewModel.SaveState(e);
        }
    }
    private void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
    {
        LoadState(e);
    }
    private void navigationHelper_SaveState(object sender, SaveStateEventArgs e)
    {
        SaveState(e);
    }
    #endregion
}

public abstract class BasePageViewModel : ViewModelBase
{
    private bool _isLoading = false;
    public bool IsLoading
    {
        get
        {
            return _isLoading;
        }
        set
        {
            if (_isLoading == value)
            {
                return;
            }
            _isLoading = value;
            RaisePropertyChanged();
        }
    }
    public virtual void LoadState(LoadStateEventArgs e)
    {
    }
    public virtual void SaveState(SaveStateEventArgs e)
    {
    }
}

public class NavigationService : INavigationService
{
    public static readonly Dictionary<Type, Type> PageDictionary;
    static NavigationService()
    {
        PageDictionary = new Dictionary<Type, Type>();
        PageDictionary.Add(typeof(LogInPageViewModel), typeof(LogInPage));
        PageDictionary.Add(typeof(RegisterUserPageViewModel), typeof(RegisterUserPage));
    }
    public bool Navigate(Type pageViewModelType, Object parameter = null)
    {
        if (PageDictionary.ContainsKey(pageViewModelType))
        {
            if (parameter != null)
            {
                return App.CurrentFrame.Navigate(PageDictionary[pageViewModelType], parameter);
            }
            else
            {
                return App.CurrentFrame.Navigate(PageDictionary[pageViewModelType]);
            }
        }
        return false;
    }
    public bool GoBack()
    {
        if (CanGoBack())
        {
            App.CurrentFrame.GoBack();
        }
        return false;
    }
    public bool CanGoBack()
    {
        return App.CurrentFrame.CanGoBack;
    }
    public bool NavigateAndRemoveSelf(Type pageViewModelType, object parameter = null)
    {
        if (Navigate(pageViewModelType, parameter))
        {
            if (App.CurrentFrame.CanGoBack)
            {
                App.CurrentFrame.BackStack.RemoveAt(App.CurrentFrame.BackStackDepth - 1);
                return true;
            }
        }
        return false;
    }
    public bool NavigateAndRemoveAll(Type pageViewModelType, object parameter = null)
    {
        if (Navigate(pageViewModelType, parameter))
        {
            while (App.CurrentFrame.CanGoBack)
            {
                App.CurrentFrame.BackStack.RemoveAt(App.CurrentFrame.BackStackDepth - 1);
            }
            return true;
        }
        return false;
    }
}

更新(解决):

这个错误是由使用通用应用程序类库引起的。

我想把NavigationHelper.cs类(在WP8应用程序中默认生成)分离到一个库中。这样我就可以直接对VM进行单元测试(我不能用单元测试项目引用WP8应用程序)。因此,我将NavigationHelper.cs类以及上面的所有相关代码放在一个新的通用应用程序类库中。

NavigationHelper类依赖于两件事,构建中的WINDOWS_PHONE_APP宏,它影响NavigationHelper类中的特定部分,HardwareButton BackPressed监听器。

#if WINDOWS_PHONE_APP
            Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
#else

和第二个依赖于Windows.Phone组件。该程序集存在于WP8应用程序中,但不存在于通用应用程序类库中。这意味着即使我将WINDOWS_PHONE_APP宏添加到库中,应用程序也不会编译。你不能在通用应用程序类库中使用Windows Phone 8/8.1项目生成的NavigationHelper。我会试着提出这个问题。谢谢!

到新页面的导航将删除backstack

Update [solved]:

这个错误是由使用通用应用程序类库引起的。

我想把NavigationHelper.cs类(在WP8应用程序中默认生成)分离到一个库中。这样我就可以直接对VM进行单元测试(我不能用单元测试项目引用WP8应用程序)。因此,我将NavigationHelper.cs类以及上面的所有相关代码放在一个新的通用应用程序类库中。

NavigationHelper类依赖于两件事,构建中的WINDOWS_PHONE_APP宏,它影响NavigationHelper类中的特定部分,HardwareButton BackPressed侦听器。

#if WINDOWS_PHONE_APP
            Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
#else
    ...
#endif

因为没有定义MACRO,返回按钮实际上不会返回。

第二个问题是缺少Windows.Phone组件。该程序集存在于WP8应用程序中,但不存在于通用应用程序类库中。这意味着即使我在库中添加WINDOWS_PHONE_APP宏,应用程序也不会编译。你不能在通用应用程序类库中使用Windows Phone 8/8.1项目生成的NavigationHelper。我会试着提出这个问题。谢谢!

你可以把你的NavigationHelper留在你的共享项目中,只要把它添加到你的Windows Phone项目的MainPage .

 static MainPage()
        {
            HardwareButtons.BackPressed += (sender, args) =>
            {
                var frame = Window.Current.Content as Frame;
                if (frame != null && frame.CanGoBack)
                {
                    frame.GoBack();
                    args.Handled = true;
                }
            };
        }

这解决了我的BackButton问题