5

我最近添加了一个自定义 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方法的类,则每当我导航到应用程序或在应用程序中调用NavigateService.Navigate()时都会调用两次MapUri

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

4

3 回答 3

3

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

于 2014-05-28T20:45:27.020 回答
0

我的代码中有些作弊只保留一个事件。

    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
    }
于 2015-03-17T04:27:39.603 回答
0

这就是我所做的:

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);
        };

看起来不错。

于 2015-03-25T07:57:01.563 回答