MVVM Silverlight и навигация по страницам - PullRequest
3 голосов
/ 16 мая 2011

Я только начинаю с Silverlight, а также с моделью MVVM. При выполнении навигации по страницам и отправке аргументов с одной страницы на другую ... является ли использование строки запроса наиболее приемлемым методом?

Кажется, существует большая путаница в том, как следует передавать аргументы при выполнении навигации по страницам. По крайней мере, я нахожу несколько тем по этому поводу на различных веб-ресурсах, но никто, похоже, не согласен с методом «наилучшей практики».

1 Ответ

2 голосов
/ 17 мая 2011

ПРИМЕЧАНИЕ: Приведенное ниже решение использования строк запроса в NavigationContext работает как в браузере, так и вне его.

Вы обычно устанавливаете свой UriMapper примерно так:

           <navigation:Frame Source="/Home" >
                <navigation:Frame.UriMapper>
                    <uriMapper:UriMapper>
                        <uriMapper:UriMapping Uri="" 
                                   MappedUri="/Views/Home.xaml"/>
                        <uriMapper:UriMapping Uri="/{pageName}/{key}" 
                                   MappedUri="/Views/{pageName}.xaml?entityGuid={key}"/>
                        <uriMapper:UriMapping Uri="/{pageName}" 
                                   MappedUri="/Views/{pageName}.xaml"/>
                    </uriMapper:UriMapper>
                </navigation:Frame.UriMapper>
            </navigation:Frame>

И затем, чтобы получить NavigationContext в модель представления, вы добавляете помощника в представление следующим образом:

<navigation:Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:helpers="clr-namespace:MyApp.Helpers"
                 xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
                 DataContext="{Binding Path=Entity, Source={StaticResource Locator}}"
                 helpers:Navigator.Source="{Binding}">

И затем у вас есть помощник по прикрепленному свойству, подобный этому (я изменил это от кого-то другого, хотя я забыл, кто):

using System.Windows;
using System.Windows.Controls;

namespace MyApp.Helpers
{

    public interface INavigable
    {
        System.Windows.Navigation.NavigationService NavigationService { get; set; }
        System.Windows.Navigation.NavigationContext NavigationContext { get; set; }
    }


    public static class Navigator
    {
        public static INavigable GetSource(DependencyObject obj)
        {
            return (INavigable)obj.GetValue(SourceProperty);
        }

        public static void SetSource(DependencyObject obj, INavigable value)
        {
            obj.SetValue(SourceProperty, value);
        }

        public static readonly DependencyProperty SourceProperty =
             DependencyProperty.RegisterAttached("Source", typeof(INavigable), typeof(Navigator), new PropertyMetadata(OnSourceChanged));

        private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Page page = (Page)d;

            page.Loaded += PageLoaded;
        }

        private static void PageLoaded(object sender, RoutedEventArgs e)
        {
            Page page = (Page)sender;

            INavigable navSource = GetSource(page);

            if (navSource != null)
            {
                navSource.NavigationService = page.NavigationService;
                navSource.NavigationContext = page.NavigationContext;
            }
        }
    }
}

А затем добавьте следующее в вашу ViewModel:

    private NavigationContext _NavigationContext;
    public NavigationContext NavigationContext {
        get { return _NavigationContext; }
        set {
            if (_NavigationContext == value)
                return;
            _NavigationContext = value;
            RaisePropertyChanged("NavigationContext");
        }
    }
    protected override void RaisePropertyChanged(string propertyName) {
        base.RaisePropertyChanged(propertyName);

        switch (propertyName) {
            case "NavigationContext":
                if (NavigationContext.QueryString.ContainsKey("entityGuid")) {
                    if (NavigationContext.QueryString["entityGuid"].Equals("new", StringComparison.InvariantCultureIgnoreCase)) {
                        LoadNewEntity();  // your 'new' logic
                    } else {
                        this.EntityGuid = new Guid(NavigationContext.QueryString["entityGuid"]);
                        LoadExistingEntity(EntityGuid);  // your 'existing' logic
                    }
                }
                break;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...