问题
I recently added a custom UriMapper for saving files into my applications isolated storage when opening them from IE. The code for this looks like this:
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;
}
}
In InitializePhoneApplication() I do a
RootFrame.UriMapper = new AssociationUriMapper();
And of course I've added the Extensions tag to WMAppManifest.xml
All this works fine... but I noticed a strange behaviour. I get two copies of the files each time I open them from IE. When I put a breakpoint inside my overridden MapUri it gets hit twice every time the application autolaunches from IE.
When I started to investigate this further I noticed that this happens whenever I call NavigateService.Navigate(). But not when I call NavigateService.GoBack.
Do anyone know why this is happening? Why are MapUri() called twice when Navigate() is called? Is it something that happens when a new instance of a page is created? (I've noticed that when we call Navigate() a new instance of the called page is created, but when we call GoBack() we retrieve the already created instance of the page we navigated from).
Edit:
I've now done a little test application from scratch. The result is the same. If I have a class that inherits from UriMapperBase and overrides the MapUri method, MapUri is called twice whenever I navigate to the application or call NavigateService.Navigate() in the application.
The obvious workaround for my problem is of course to have a separate page that the application navigates to and that page call SaveFileToIsolatedStorage(). But that still doesn't answer the question why the behaviour is as it is.
回答1:
Try hooking up the UriMapper through the XAML of the MainPage using a ViewModel instead of through code.
回答2:
Some cheat in my code to keep only one event.
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:
that is what I do:
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;
}
}
in App.cs:
RootFrame.Navigating += (s, e) =>
{
AppUriMapper.IsNavigating = true;
System.Diagnostics.Debug.WriteLine("goto: [mode] {0}, [uri] {1}", e.NavigationMode, e.Uri);
};
look ok.
来源:https://stackoverflow.com/questions/21901124/windows-phone-app-calls-mapuri-twice-when-i-call-navigateservice-navigate