开发者

mvvmlight - what's the "proper way" of picking up url parameters for a view model

I'm just switching a project across to mvvmlight and trying to do things "the right way"

I've got a simple app with a listbox

When an item is selected in the listbox, then I've hooked up a RelayCommand

This RelayCommand causes a call on an INavigationService (http://geekswithblogs.开发者_运维问答net/lbugnion/archive/2011/01/06/navigation-in-a-wp7-application-with-mvvm-light.aspx) which navigates to a url like "/DetailPage.xaml?DetailId=12"

The DetailPage.xaml is then loaded and ... this is where I'm a bit unsure...

  • how should the DetailPage get hooked up to a DetailView with DetailId of 12?
  • should I do this in Xaml somehow using a property on the ViewLocator?
  • should I do this in the NavigatedTo method?

Please feel free to point me to a full sample - sure this has been done a (hundred) thousand times before, but all the blogs and tutorials seem to be skipping this last trivial detail (focussing instead on the messaging and on the ioc on on the navigationservice)

Thanks!


The only place you can retrieve the URL parameter is in the view. So since your view is likely depending on it, you should fetch it in the OnNavigatedTo method.

Then, you should pass it along to your viewmodel, either using messaging (to expensive if you ask me), or by referring to your datacontext (which is the viewmodel I presume), and execeuting a method on that.

private AddTilePageViewModel ViewModel
{
    get
    {
        return DataContext as AddTilePageViewModel;
    }
}

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    var postalCode = NavigationContext.TryGetKey("PostalCode");
    var country = NavigationContext.TryGetStringKey("Country");

    if (postalCode.HasValue && string.IsNullOrEmpty(country) == false)
    {
        ViewModel.LoadCity(postalCode.Value, country);
    }

    base.OnNavigatedTo(e);
}

I'm using some special extensions for the NavigationContext to make it easier.

namespace System.Windows.Navigation
{
    public static class NavigationExtensions
    {
        public static int? TryGetKey(this NavigationContext source, string key)
        {
            if (source.QueryString.ContainsKey(key))
            {
                string value = source.QueryString[key];

                int result = 0;
                if (int.TryParse(value, out result))
                {
                    return result;
                }
            }

            return null;
        }

        public static string TryGetStringKey(this NavigationContext source, string key)
        {
            if (source.QueryString.ContainsKey(key))
            {
                return source.QueryString[key];
            }

            return null;
        }
    }
}


Create a new WindowsPhoneDataBound application, it has an example of how to handle navigation between views. Basically you handle the navigation part in your view, then set the view's DataContext accord to the query string. I think it plays nicely with the MVVM pattern since your ViewModels don't have to know anything about navigation (which IMO should be handled at the UI level).

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜