views:

2108

answers:

5

Hi, im developing a silverlight 3 beta navigation application, so i've gone with a slight variation of the MVVM pattern :) (all-in-one viewmodel), using prism, and stuff.

Question: How do i navigate to a different "NavigationPage" in the viewmodel

Now to cut a long story short, the viewmodel is declared as a page resource.

<navigation:Page.Resources>
    <mvvm:LoginModel x:Key="DataSource" d:IsDataSource="True"></mvvm:LoginModel>
</navigation:Page.Resources>

And then a command is used to wireup everything with the viewmodel

<Button x:Name="LoginButton" Width="100"  Margin="8" Content="Login"
        prism:Click.Command="{Binding LoginCommand}"/>

Now if i try to navigate anywhere in the viewmodel like so

this.NavigationService.Navigate(new Uri("/Views/About.xaml", UriKind.Relative));

the Navigationservice is null, i've looked around and found this article, which describes using helix 0.3 for navigation, this was built back in the sl2 days, when the navigation controls never existed, now helix's model works well, and by implementing INavigationAware in the viewmodel, you are able to gain access to the NavigationContext, and then do whatever it is you require, i have tried helix, and it works.

SL3 comes with the builtin Navigation support, so to speak, which does exactly what helix does. So i dont wanna use a 3rd party framework, instead i prefer to use the built in sl3 features.

Is there anything in SL3 that emulates the helix's INavigationAware interface?

A: 

okay to help my question along, cos there still hasn't been any answer, i'm gonna throw more information at it.

This is the code in the viewmodel

public LoginModel()
    {
        LoginCommand = new DelegateCommand<object>(LoginCommandExecuted, a => { return _CanLoginCommandExecute; });
    }

    public ICommand LoginCommand { get; private set; }
    private bool _CanLoginCommandExecute = true;
    private void LoginCommandExecuted(object parameter)

    {
        _CanLoginCommandExecute = false;

        AdminClient client = new AdminClient();
        client.AuthorizeAsync();
        client.AuthorizeCompleted += 
        new EventHandler<AsyncCompletedEventArgs>(
                (s, e) =>
                {
                    if (e.Error != null)
                    {
                        MessageBox.Show("Login Failed");
                    }
                    else
                    {
                        this.NavigationService.Navigate(new Uri("/Views/About.xaml", UriKind.Relative));
                    }
                    _CanLoginCommandExecute = true;
                }
                );

    }

NavigationService is null, therefore i cant move to the next view, help!!!

Neil
so far this is the closest thing to a solution i've found >>http://blogs.southworks.net/mconverti/2009/04/12/how-to-integrate-a-prism-v2-application-with-the-silverlight-3-navigation-framework/#_Download
Neil
+1  A: 

A dodgy fix, but the only thing i've been able to use to get this working. In the OnNavigatedTo event in the view, access the ViewModel and set the NavigationService to a property in the viewmodel so that it can be used later in the viewmodel

    protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            ViewModels.LoginViewModel viewmodel = (ViewModels.LoginViewModel)this.Resources["DataSource"];
//DataSource being the x:Name given to the viewmodel that is loaded as a page resource
            viewmodel .service = NavigationService;
        }
Neil
+3  A: 

I personally think NavigationService is a UI-concept associated with the UI Frame or Page.

Another way to accomplish this without having to pass in a NavigationService into the view model is to have the ViewModel raise an event when navigation is supposed to occur... have the view handle the view model event and call Navigate in response.

NikhilK
I 100% agree, okay, so i created the event which is raised when a ViewModel requests a navigation, then from the View, i still need to access the viewmodel from the Page resources (like previous solution) only this time, i dont add the navigation service to the ViewModel, rather tell the View to listen for the event and navigate accordinly, correct?
Neil
Yep, you got it... no need to pass in something like a NavigationService into the view model.
NikhilK
A: 

NavigationService.Navigate(new Uri("/About", UriKind.Relative)); Above should work.

vadaapaav
There is no access to the NavigationService in the ViewModel, hence why the View must subscribe to an event that the viewmodel will fire when it wishes the view to navigate for it, This is a View first approach to MVVM
Neil
A: 

You may want to consider using the Messaging system if you are using MVVM light. Have a listener on your page hosting the frame that does the navigation and send the nav messages from your view models.

Bryce
This is my current strategy, thanks
Neil