我只是从Silverlight和MVVM模型开始。
当执行页面导航并将参数从一页发送到另一页时,..使用querystring是最常用的方法吗?

在执行页面导航时应如何传递参数似乎是一个很大的困惑。至少我在各种Web资源上都找到了与此相关的几个主题,但是似乎没人同意“最佳实践”方法。

最佳答案

注意:以下在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放入 View 模型中,您可以向 View 中添加一个助手,如下所示:
<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;
        }
    }

10-08 14:04