当我使用MVVM模式和MVVM Light点击后退按钮时如何回到预览页面?

时间:2015-12-30 17:30:18

标签: mvvm windows-phone-8.1 mvvm-light

我有一个测试应用程序来测试Windows Phone 8.1上的导航,我可以从主页面到第二页进入第二页。

问题是,当我单击后退按钮时,我返回桌面屏幕,应用程序转到后台,所以我必须按住后退按钮才能返回应用程序。

我见过覆盖backButtonKeyPressed事件的示例,但这是在页面后面的代码中,所以这不适合我的情况因为我想使用MVVM。

在我的应用程序中,控制goBack事件的代码位于NavigationSerive中。

真的,我无法在MVVM中找到解决此问题的好例子。使用MVVM Light并不是强制性的,如果有其他方式使用MVVM模式,对我有好处。

感谢。

1 个答案:

答案 0 :(得分:2)

这是我实施的导航服务。不会声称它是完美的,但它对我有用。这也是MVVM Light 5中内置导航服务的预定日期,但您仍然可以使用它或部分内容。

使用

在ViewModelLocator中注册

SimpleIoc.Default.Register<INavigationService, NavigationService>();

然后通过构造函数将其注入到视图模型中。使用NavigateTo()导航到其他页面;后退按钮按下处理程序仅在没有更多历史记录时退出应用程序,否则导航到上一页。

public interface INavigationService
{
    void NavigateTo(Type pageType, object parameter = null);

    void NavigateTo(string pageName, object parameter = null);

    void GoBack();
}

public class NavigationService : INavigationService
{
    #region Public

    /// <summary>
    /// Navigates to a specified page.
    /// </summary>
    public void NavigateTo(string pageName, object parameter = null)
    {
        Type pageType = Type.GetType(string.Format("SendToSync.{0}", pageName));

        if (pageType == null)
            throw new Exception(string.Format("Unknown page type '{0}'", pageName));

        NavigateTo(pageType, parameter);
    }

    /// <summary>
    /// Navigates to a specified page.
    /// </summary>
    public void NavigateTo(Type pageType, object parameter = null)
    {
        var content = Window.Current.Content;
        var frame = content as Frame;

        if (frame != null)
        {
            var previousPageType = frame.Content.GetType();

            if (previousPageType != pageType)
                NavigationHistory.Add(previousPageType);

            //await frame.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => frame.Navigate(pageType));

            frame.Navigate(pageType, parameter);
        }

        Window.Current.Activate();
    }

    /// <summary>
    /// Goes back.
    /// </summary>
    public void GoBack()
    {
        var content = Window.Current.Content;
        var frame = content as Frame;

        if (frame != null)
        {
            var currentPageType = frame.Content.GetType();

            // remove the previous page from the history

            var previousPageType = NavigationHistory.Last();
            NavigationHistory.Remove(previousPageType);

            // navigate back

            frame.Navigate(previousPageType, null);
        }
    }

    #endregion

    #region Private

    /// <summary>
    /// The navigation history.
    /// </summary>
    private List<Type> NavigationHistory { get; set; }

    #endregion

    #region Initialization

    public NavigationService()
    {
        NavigationHistory = new List<Type>();

        HardwareButtons.BackPressed += HardwareButtons_BackPressed;
    }

    /// <summary>
    /// Called when the back button is pressed; either navigates to the previous page or exits the application.
    /// </summary>
    private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
    {
        if (NavigationHistory.Count == 0)
        {
            e.Handled = false;
        }
        else
        {
            e.Handled = true;
            GoBack();
        }
    }

    #endregion
}

编辑:我的ViewModelLocator的部分内容

在构造函数中:

SimpleIoc.Default.Register<MainViewModel>();

以及随附的财产:

public MainViewModel MainViewModel
{
    get { return ServiceLocator.Current.GetInstance<MainViewModel>();  }
}

这将始终返回MainViewModel的相同单个实例(并且视图模型数据将保持不变)。