【问题标题】:MVVM using Page Navigation On Windows Phone 7MVVM 在 Windows Phone 7 上使用页面导航
【发布时间】:2010-05-09 10:19:32
【问题描述】:

Windows Phone 7 中的导航框架是 Silverlight 中的精简版。您只能导航到 Uri 而不能传入视图。由于 NavigationService 与 View 绑定,人们如何使其适合 MVVM。例如:

public class ViewModel : IViewModel
{
    private IUnityContainer container;
    private IView view;

    public ViewModel(IUnityContainer container, IView view)
    {
        this.container = container;
        this.view = view;
    }

    public ICommand GoToNextPageCommand { get { ... } }

    public IView { get { return this.view; } }

    public void GoToNextPage()
    {
        // What do I put here.
    }
}

public class View : PhoneApplicationPage, IView
{
    ...

    public void SetModel(IViewModel model) { ... }
}

我正在使用 Unity IOC 容器。我必须先解析我的视图模型,然后使用 View 属性来获取视图,然后再显示它。但是使用 NavigationService,我必须传入一个视图 Uri。我没有办法先创建视图模型。有没有办法解决这个问题。

【问题讨论】:

    标签: mvvm windows-phone-7 navigation


    【解决方案1】:

    而不是通过构造函数传递视图。您可以先通过 NavigationService 构建视图并将其传递给视图模型。像这样:

    public class ViewModel : IViewModel
    {
        private IUnityContainer container;
        private IView view;
    
        public ViewModel(IUnityContainer container)
        {
            this.container = container;
        }
    
        public ICommand GoToNextPageCommand { get { ... } }
    
        public IView 
        { 
            get { return this.view; } 
            set { this.view = value; this.view.SetModel(this); }
        }
    
        public void GoToNextPage()
        {
            // What do I put here.
        }
    }
    
    PhoneApplicationFrame frame = Application.Current.RootVisual;
    bool success = frame.Navigate(new Uri("View Uri"));
    
    if (success)
    {
        // I'm not sure if the frame's Content property will give you the current view.
        IView view = (IView)frame.Content;
        IViewModel viewModel = this.unityContainer.Resolve<IViewModel>();
        viewModel.View = view;
    }
    

    【讨论】:

      【解决方案2】:

      如果您使用的是 Mvvm Light,您可以尝试:

      Windows Phone 7 — Navigation between pages using MVVM Light Messaging

      (见类似帖子:Silverlight Navigation using Mvvm-light(oobe)+MEF?)

      【讨论】:

        【解决方案3】:

        我的意见是视图模型应该在应用程序启动时创建和注册。通过将它放在根 DataContext 中,所有页面都将自动获得对它的引用,而无需任何代码隐藏或 IoC 技巧。

            // Code to execute when the application is launching (eg, from Start)
            // This code will not execute when the application is reactivated
            private void Application_Launching(object sender, LaunchingEventArgs e)
            {
                m_ViewModel = new PrimaryViewModel(RootFrame) ;
                RootFrame.DataContext = m_ViewModel;
            }
        
            // Code to execute when the application is activated (brought to foreground)
            // This code will not execute when the application is first launched
            private void Application_Activated(object sender, ActivatedEventArgs e)
            {
                m_ViewModel = new PrimaryViewModel(RootFrame) ;
                m_ViewModel.Activated(PhoneApplicationService.Current.State);
                RootFrame.DataContext = m_ViewModel;
            }
        

        【讨论】:

          【解决方案4】:

          如果您使用的是 MVVM 架构,那么您可以在使用 Messenger 注册后传递 navigationPage。使用字符串(例如 PageName)变量创建模型类(例如 NavigateToPageMes​​sage)。您想将字符串从 homepage.xaml 传递给 newpage.xaml,然后在 Homepage viewmodel 中只需在您绑定的命令下发送这样的消息(比如 HomeNavigationCommand)

          private void HomeNavigationCommandHandler()
                  {
                      Messenger.Default.Send(new NavigateToPageMessage {PageName = "newpage"});
                  }
          

          在newpage Viewmodel中,你应该像这样注册messenger,

          Messenger.Default.Register<NavigateToPageMessage>(this, (action) => ReceiveMessage(action));
          
           private object ReceiveMessage(NavigateToPageMessage action)
                  {
                      var page = string.Format("/Views/{0}.xaml", action.PageName);           
                      NavigationService.Navigate(new System.Uri(page,System.UriKind.Relative));
                      return null;
                  }
          

          //假设您的视图在视图文件夹中

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多