WP7 Navigation & Passing Context to a ViewModel

Jun 29, 2010 at 1:33 PM
I just started using nRoute and I love it. I had a question about how to pass context to a viewmodel though. On one page I have a listbox. On the selected list item changed I'd like to navigate to a detail page and pass the selected item which could be used in th view model constructor. Any thoughts on the best way to do that? It seems like NavigateAction would do that, but it also seems like I need to use one of the navigation controls. I'd rather not have all my view contained in that because i want to use the PageNavigationFrame that is the root element in WP7. Otherwise the app doesn't handle the back button key press properly. The code I have is basically: MainPage.xaml <ListBox x:Name="FeaturedList" ItemsSource="{Binding Streams}"> StreamPlayer.xaml just has the <nBehaviors:BridgeViewModelBehavior/> and some controls that bind to a specific stream StreamPlayer.xaml.cs [MapView(typeof(StreamPlayerViewModel))] public partial class StreamPlayer : PhoneApplicationPage { and the view model for the streamplayer page ideally would be like public class StreamPlayerViewModel : ViewModelBase { public StreamPlayerViewModel(Stream stream) { } } Can one of the actions send the selected item to the StreamPlayer page to be used in the viewmodel or can i make a command that calls navigate and passes context somehow? Thanks, kevin
Coordinator
Jun 30, 2010 at 6:53 PM

Hi Kevin, great question I held back answering it till this post (http://www.orktane.com/Blog/post/2010/06/30/Creating-a-Netflix-App-using-nRoute-A-Step-by-Step-Guide.aspx) was out, as it deals with passing values to ViewModels. But I'll just point out you can't have binded navigation parameters in WP7 because of binding limitations (see http://www.orktane.com/Blog/post/2010/04/28/nRoute-More-Wholesomeness-with-SL-4-and-NET-40.aspx) though you could bind the navigation parameters in its entirety (so it's still possible)!

Anyway, with regards passing values to a VM in WP7:

- You could possibly have a third party hold the value and the pass it off to the VM, though obviously this is quite clumsy
- You could also possibly do it using a code-behind pass off (as MS samples do), but that's even worse
- I think a better way would be to have a solitary PageNavigationFrame and then within it you run nRoute's navigation containers and feed it with info on when the back button is pressed. You could also link it in a way that whenever the back button is pressed the navigation container executes that as navigating back 

I've been thinking about creating an abstraction layer over WP7 navigation controls so you can run nRoute and still enjoy things like the command bar type native controls or interfacing with the hardware buttons. Also I personally feel that MS has done a mistake by forcing one model to create all type of apps in WP7. Interfacing with native controls and events could have been better handled using various extensibility mechanisms in XAML/SL. 

Hope this helps,
Rishi

Nov 23, 2010 at 10:45 AM

Hi,

 

After different test, I finaly find a "clean" solution. I create a property in my ViewModel which expose ParametersCollection and used ParametersBinding on my NavigateAction.

 

In ViewModel :

public ParametersCollection Parameters
{
    get
    {
        ParametersCollection param = new ParametersCollection();
        param.Add("id", id);
        return param;
    }
}

In View :

<i:Interaction.Triggers>
    <i:EventTrigger EventName="MouseLeftButtonDown">
        <n:NavigateAction Url="Views/ParkingDetails" ParametersBinding="{Binding Parameters}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

 

And it work for me on WP7 :)

 

 

Coordinator
Dec 8, 2010 at 9:23 AM

@crazyht, I believe this has been supported since SL3 - one thing I can add is that you can use a ValueConverter and bind the parameters to the Id directly (see nRoute's easy way to do this: http://www.orktane.com/Blog/post/2009/08/25/Value-Converter-and-Command-Relays-for-Visual-Logic.aspx).

Rishi

Jan 4, 2011 at 3:32 PM
Orktane wrote:

Hi Kevin, great question I held back answering it till this post (http://www.orktane.com/Blog/post/2010/06/30/Creating-a-Netflix-App-using-nRoute-A-Step-by-Step-Guide.aspx) was out, as it deals with passing values to ViewModels. But I'll just point out you can't have binded navigation parameters in WP7 because of binding limitations (see http://www.orktane.com/Blog/post/2010/04/28/nRoute-More-Wholesomeness-with-SL-4-and-NET-40.aspx) though you could bind the navigation parameters in its entirety (so it's still possible)!

Anyway, with regards passing values to a VM in WP7:

- You could possibly have a third party hold the value and the pass it off to the VM, though obviously this is quite clumsy
- You could also possibly do it using a code-behind pass off (as MS samples do), but that's even worse
- I think a better way would be to have a solitary PageNavigationFrame and then within it you run nRoute's navigation containers and feed it with info on when the back button is pressed. You could also link it in a way that whenever the back button is pressed the navigation container executes that as navigating back 

I've been thinking about creating an abstraction layer over WP7 navigation controls so you can run nRoute and still enjoy things like the command bar type native controls or interfacing with the hardware buttons. Also I personally feel that MS has done a mistake by forcing one model to create all type of apps in WP7. Interfacing with native controls and events could have been better handled using various extensibility mechanisms in XAML/SL. 

Hope this helps,
Rishi

Hi Rishi,

 

di you work on the abstraction for navigation in WP7?

It would be greate, or do you have an idea how i can navigate between pages and passing a context?

 

Best reagards

  Dima

Coordinator
Jan 5, 2011 at 12:42 PM

@Dima, I am working on it right now - evaluating some options, and I will let you know when I have something checked in.

Cheers,
Rishi