【问题标题】:How back to previews page when I click back button using MVVM pattern and MVVM Light?当我使用 MVVM 模式和 MVVM Light 单击返回按钮时,如何返回上一页?
【发布时间】:2016-04-04 16:57:17
【问题描述】:

我有一个测试应用程序来测试 windows phone 8.1 上的导航,我可以从我的主页转到第二页。

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

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

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

我真的找不到在 MVVM 中解决这个问题的好例子。 MVVM Light不是必须的,如果有其他使用MVVM模式的方式,对我有好处。

谢谢。

【问题讨论】:

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


    【解决方案1】:

    这是我实现的导航服务。不会声称它是完美的,但它对我有用。这也早于 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&lt;MainViewModel&gt;();

    以及附带的属性:

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

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

    【讨论】:

    • 这就是我需要的。只是一个疑问,我注意到如果我有一个文本框,例如我设置的文本并转到另一个页面,当我返回上一页时,文本框是空的,所以我猜在这种情况下是实例化一个新的页面一个新的视图模型。是否可以保留这些数据?谢谢。
    • 如果您使用SimpleIoc.Default.Register&lt;MyViewModel&gt;() 设置视图模型,它应该默认注册为单例,因此导航回应该只使用现有的视图模型实例(数据完整)而不是创建一个新的。当我有一个包含搜索结果的页面并导航离开和返回时,搜索结果仍然完好无损。
    • 谢谢。问题是我必须以两种方式设置绑定模式,如果没有,则视图模型中的 porpery 不会从视图中更新。所以在 WPF 中默认值是 twoWays 而不是 WP8.1 中的 OneWay。
    猜你喜欢
    • 2011-03-10
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2010-11-14
    • 2023-02-01
    • 1970-01-01
    相关资源
    最近更新 更多