【问题标题】:What's the best way to transfer data to another XAML page?将数据传输到另一个 XAML 页面的最佳方式是什么?
【发布时间】:2012-12-18 03:37:30
【问题描述】:

在传递数据时导航到另一个 XAML 页面的文档化方法似乎是将数据序列化为 URL 参数。这适用于简单的参数,例如单个数据库键:

NavigationService.Navigate(new Uri("/ViewContact.xaml?contactid=" + cid, UriKind.Relative));

但是,如果您想传入一个相当复杂的数据结构,例如搜索查询,该怎么办?该查询可能有关键字、各种过滤器、项目数组等。使用 URL 参数表示此类数据将相当困难。

问题:导航到另一个页面的推荐技术是什么,传入重要的参数?

一个想法是首先将数据或查询设置为您要导航到的页面的静态属性:

Query q = new Query();
// Set various parameters
ViewContact.SearchQuery = q;
NavigationService.Navigate(new Uri("/ViewContact.xaml?contactid=", UriKind.Relative));

然后,当加载 ViewContact 时,它会检查该静态属性并将数据加载到内存中。

这种方法有什么问题,或者有其他推荐的方法吗?

【问题讨论】:

    标签: silverlight xaml windows-phone windows-phone-8


    【解决方案1】:

    看看 Prism 讨论板上的这个话题:Navigation using Object as parameter

    接近尾声,有一个使用派生自UriNavigationUri 类的解决方案:

    public sealed class NavigationUri : Uri
    {
      public NavigationUri(string uri)
        : base(uri, UriKind.Relative)
      {
        Parameters = new Dictionary<string, object>();
      }
    
      public Dictionary<string, object> Parameters
      {
        get;
        private set;
      }
    }
    

    (我公开了构造函数)

    然后你可以像这样使用它:

    var uri = new NavigationUri("/ViewContact.xaml");
    uri.Parameters["SearchQuery"] = q;
    NavigationService.Navigate(uri);
    

    然后,在您的ViewContactOnNavigatedTo 方法中:

    public override void OnNavigatedTo(NavigationContext navigationContext)
    {
      var uri = (NavigationUri)navigationContext.Uri;
      SearchQuery = (Query) uri.Parameters["SearchQuery"];
    }
    

    按照原帖中的建议,您还可以使用类来生成参数键,而不是硬编码:

    public sealed class NavigationUriParameters
    {
        public static readonly string SearchQuery = Guid.NewGuid().ToString();
    }
    

    【讨论】:

    • 这很有趣——我会小心测试应用程序何时被墓碑化,如果参数和 Uri 都恢复了,我会小心地测试它。
    • 是的。我通常使用这两种机制:如果我需要的数据已经加载到内存中(例如在从中导航的 View 中),则使用这种机制,如果尚未加载数据,则使用原始 Uri 参数作为后备。
    • +1 这个想法.. 但是,是的,看起来有点老套,我必须测试以确保它与后退/前进堆栈一起工作。
    【解决方案2】:

    在我的应用中,我在 URL 参数中传递了某种标识符,例如

    /FlightInfo.xaml?FlightID=4
    

    然后在 OnNavigatedTo() 方法中查找该航班 ID。航班存储在 ViewModel 中,我将其作为静态属性保存在某处,因此它很相似,但这样您的 URL 是有意义的,并且返回/恢复会更好地工作。

    【讨论】:

      【解决方案3】:

      如果您正在为 Silverlight 开发并希望支持深度链接,则必须将加载数据和显示页面所需的所有信息放在 URL 中,因为 url 是存储在链接中的内容。

      在所有其他情况下(Silverlight 没有深度链接或 Windows Phone),您可以将信息(部分)存储在某个全局可用对象(例如应用程序)中的其他位置。

      如上所述,您可以传递对象的标识符并在加载页面时检索对象(从服务或缓存中获取)

      您还可以将当前的 ViewModel/Data 存储在 App 对象中,然后简单地将其绑定到新页面。

      根据可用资源的数量(时间、带宽、并发用户...),您可能希望选择其中之一,甚至根据场景在解决方案之间切换。

      【讨论】:

      • 我所说的场景是如果没有一个简单的标识符来检索对象。在这种情况下,我试图传递无法通过 URL 参数轻松表达的搜索条件。我认为只是异步进行搜索并将其存储在 App 对象上是正确的方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 2021-04-28
      • 2019-12-14
      • 2011-03-13
      • 1970-01-01
      • 2018-06-12
      相关资源
      最近更新 更多