开发者

MVVM using Page Navigation On Windows Phone 7

The Navigation framework in Windows Phone 7 is a cut down version of what is in Silverlight. You can only navigate to a Uri and not pass in a view. Since the NavigationService is tied to the View, how do people get this to fit into MVVM. For example:

public class ViewMod开发者_如何学Goel : 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) { ... }
}

I am using the Unity IOC container. I have to resolve my view model first and then use the View property to get hold of the view and then show it. However using the NavigationService, I have to pass in a view Uri. There is no way for me to create the view model first. Is there a way to get around this.


Instead of passing the view through the constructor. You could construct the view first via the NavigationService and pass it into the view-model. Like so:

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;
}


If you are using Mvvm Light you could try:

Windows Phone 7 — Navigation between pages using MVVM Light Messaging

(See similar post: Silverlight Navigation using Mvvm-light(oobe)+MEF?)


My opinion is that the view-model should be created and registered at application startup. By placing it inside the root DataContext all pages will automatically get a reference to it without any code-behind or IoC tricks.

    // 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;
    }


If you are using MVVM architecture,then you can pass navigationPage after registering using Messenger. Create a model class (say NavigateToPageMessage) with a string(say PageName) variable. You want to pass string from homepage.xaml to newpage.xaml,then in Homepage viewmodel just send the message like this under the command you binded (say HomeNavigationCommand)

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

In the newpage Viewmodel,you should register the messenger like this,

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;
        }

//Assuming your views are in View Folder

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜