【问题标题】:Windows Phone app calls MapUri() twice when I call NavigateService.Navigate()当我调用 NavigationService.Navigate() 时,Windows Phone 应用程序调用 MapUri() 两次
【发布时间】:2014-02-20 07:34:15
【问题描述】:

我最近添加了一个自定义 UriMapper,用于在从 IE 打开文件时将文件保存到我的应用程序隔离存储中。代码如下所示:

class AssociationUriMapper : UriMapperBase
{
    public override Uri MapUri(Uri uri)
    {
        var tempUri = uri.ToString();

        if (tempUri.Contains("/FileTypeAssociation"))
        {                
            int fileIdIndex = tempUri.IndexOf("fileToken=") + 10;
            string fileId = tempUri.Substring(fileIdIndex);

            SaveFileToIsolatedStorage(fileId);

            return new Uri("/MainPage.xaml", UriKind.Relative);                
        }

        return uri;
    }
}

InitializePhoneApplication() 我做了一个

RootFrame.UriMapper = new AssociationUriMapper();

当然,我已经将 Extensions 标签添加到 WMAppManifest.xml

这一切都很好......但我注意到一个奇怪的行为。每次从 IE 打开文件时,我都会得到两份文件。当我在覆盖的 MapUri 中放置一个断点时,每次应用程序从 IE 自动启动时它都会被命中两次。

当我开始对此进行进一步调查时,我注意到每当我打电话时都会发生这种情况 NavigateService.Navigate()。但当我调用 NavigateService.GoBack 时不会。

有人知道为什么会这样吗?为什么在调用 Navigate() 时会调用两次 MapUri()?创建页面的新实例时会发生这种情况吗? (我注意到,当我们调用 Navigate() 时,会创建一个被调用页面的新实例,但是当我们调用 GoBack() 时,我们会检索已创建的我们从中导航的页面)。

编辑:
我现在从头开始做了一个小测试应用程序。结果是一样的。如果我有一个继承自 UriMapperBase 并重写 MapUri 方法的类,则每当我导航到应用程序或调用 MapUri 时都会调用两次>NavigateService.Navigate() 在应用程序中。

对于我的问题,显而易见的解决方法当然是有一个单独的页面供应用程序导航到该页面并调用 SaveFileToIsolatedStorage()。但这仍然不能回答为什么行为是这样的问题。

【问题讨论】:

  • 我也有同样的问题,我的应用程序的行为真的很烦人
  • 是的。这很奇怪。它肯定与创建页面的新对象时如何调用事物有关。某种调用 MapUri() 两次的往返。无论如何,您可以将您的逻辑从 MapUri() 方法中移开吗?如果您在单独的视图中在 OnNavigatedTo() 中执行逻辑而不在构造函数中调用 Initialize(),然后导航回您要显示的页面,则逻辑将只运行一次,用户将看不到您的页面导航到,因为您没有初始化它。这就是我解决问题的方法。
  • 感谢您的提示,它可能很有用

标签: c# map windows-phone uri navigateuri


【解决方案1】:

尝试使用 ViewModel 而不是通过代码通过 MainPage 的 XAML 连接 UriMapper。

【讨论】:

  • 好提示。会试试的。
  • 你能给我一个链接来解释这意味着什么以及如何尝试吗?
【解决方案2】:

在我的代码中作弊,只保留一个事件。

    private static string lockUri = "";

    public override Uri MapUri(Uri uri)
    {
        lock (lockUri)
        {
            if (lockUri != uri.ToString())
            {
                lockUri = uri.ToString();
                return null;
            }
        }

        // Your code to route here
    }

【讨论】:

    【解决方案3】:

    这就是我所做的:

    public class AppUriMapper : UriMapperBase
    {
        public static bool IsNavigating = false;
    
        public override Uri MapUri(Uri uri)
        {
            var endUri = uri;
    
            if (IsNavigating)
            {
                IsNavigating = false;
    
                //blabla......
            }
    
            System.Diagnostics.Debug.WriteLine("goto: [origin] {0} [dest] {1}", uri, endUri);
    
            return endUri;
        }
    }
    

    在 App.cs 中:

    RootFrame.Navigating += (s, e) =>
            {
                AppUriMapper.IsNavigating = true;
                System.Diagnostics.Debug.WriteLine("goto: [mode] {0}, [uri] {1}", e.NavigationMode, e.Uri);
            };
    

    看起来不错。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多