【问题标题】:How to manage back stack when navigating to page from secondary tile从辅助磁贴导航到页面时如何管理回栈
【发布时间】:2012-08-15 19:55:11
【问题描述】:

我已经在我的应用程序中实现了辅助磁贴,因此用户可以将辅助磁贴固定到开始屏幕,然后相应地导航到我的应用程序中的相应页面。这个实现工作正常,除了当用户从固定的辅助磁贴导航到特定页面后点击后退硬件按钮时,什么都没有发生?事实上,虽然用户是从开始屏幕来的,但应用程序中的前一页实际上会显示一秒钟。如用户期望的那样实际返回到开始屏幕的正确方法是什么(我假设这将是正确的返回堆栈导航)?

我所拥有的如下,但仅适用于正常页面导航场景,而不是当用户从开始屏幕固定磁贴导航到 SharePage 时。

MainPage.xaml.cs

protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        string _title = null;
        NavigationContext.QueryString.TryGetValue("Param", out _title);

        if (_title != null)
        {
            switch (_title)
            {
                case "status":
                    this.NavigationService.Navigate(new Uri("/Views/ShareStatusPage.xaml", UriKind.Relative));
                    break;
                case "link":
                    this.NavigationService.Navigate(new Uri("/Views/ShareLinkPage.xaml", UriKind.Relative));
                    break;
            }
        }            
    }

private void CreateLiveTile(TileItem item)
    {
        string tileParameter = "Param=" + item.Title.ToString();

        ShellTile Tile = CheckIfTileExist(tileParameter);  // Check if Tile's title has been used 

        if (Tile == null)
        {
            try
            {
                var LiveTile = new StandardTileData
                {
                    Title = item.TileName,
                    //BackgroundImage = ((System.Windows.Media.Imaging.BitmapImage)hubtile.Source).UriSource,
                    BackgroundImage = new Uri(item.ImageUri.ToString(), UriKind.Relative),
                    //Count = 1,
                    BackTitle = item.TileName,
                    //BackBackgroundImage = new Uri("", UriKind.Relative),
                    BackContent = item.Message,
                };

                ShellTile.Create(new Uri("/MainPage.xaml?" + tileParameter, UriKind.Relative), LiveTile);  //pass the tile parameter as the QueryString

            }
            catch (Exception)
            {
                MessageBox.Show("This tile could not be pinned", "Warning", MessageBoxButton.OK);
            }
        }
        else
        {
            MessageBox.Show("This tile has already been pinned", "Notice", MessageBoxButton.OK);
        }
    }

private ShellTile CheckIfTileExist(string tileUri)
    {
        ShellTile shellTile = ShellTile.ActiveTiles.FirstOrDefault(tile => tile.NavigationUri.ToString().Contains(tileUri));
        return shellTile;
    }

SharePage.xaml.cs

protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
    {
        base.OnBackKeyPress(e);

        //return to the previous page in the phones back stack?
        if (NavigationService.CanGoBack)
        {
            e.Cancel = true;
            NavigationService.GoBack();
        }
        //else
        //{
        //    ??
        //}
    }

到目前为止,CreateLiveTile() 方法创建了辅助磁贴,然后当按下该磁贴时,将导航到 MainPage,然后在 MainPage OnNavigatedTo 事件中检查查询字符串,然后根据辅助磁贴加载相应的页面点击。一旦执行此操作并加载了相应的页面,我就不能再按后退按钮返回开始屏幕以遵循标准的 backstack 行为。我该如何解决这个问题?

【问题讨论】:

    标签: c# windows-phone-7


    【解决方案1】:

    根据你的新更新,我们来看看这个方法:

    private void CreateLiveTile(TileItem item)
    {
        string tileParameter = "Param=" + item.Title.ToString();
         //...
    
        if (Tile == null)
        {
            try
            {
                var LiveTile = new StandardTileData
                {
                  //...
                };
    
                ShellTile.Create(new Uri("/MainPage.xaml?" + tileParameter, UriKind.Relative), LiveTile);  //pass the tile parameter as the QueryString
    
              //blah-blah-blah
    }
    

    在这里您创建一个新图块并将tileParameter 传递给MainPage。因此,您导航到主页,然后检测 tile 参数中的文本,然后导航到 ShareLinkShareStatus 页面。这就是为什么你有一个肮脏的导航堆栈。

    让我建议您避免这种情况的方法:

    private void CreateLiveTile(TileItem item)
        {
    
        var title =  item.Title.ToString();
         //...
    
        if (Tile == null)
        {
            try
            {
                var LiveTile = new StandardTileData
                {
                  //...
                };
                 string page;
            switch (title)
            {
                case "status":
                    page = "/Views/ShareStatusPage.xaml";
                    break;
                case "link":
                    page = "/Views/ShareLinkPage.xaml");
                    break;
            }                
            if(string.IsNullOrEmpty(page))
             { 
                 //handle this situation. for example: page = "/MainPage.xaml";
             }
                ShellTile.Create(new Uri(page, UriKind.Relative), LiveTile); 
    
              //blah-blah-blah
    }
    

    当用户点击您的辅助磁贴时,他将直接导航到ShareLinkShareStatus 页面。 NavigationStack 将是干净的。当用户按下Back 按钮时,应用程序将关闭,用户将看到一个开始屏幕(这是辅助磁贴的右后退按钮行为)。

    附言不要忘记启动所有服务或加载所有资源(如果有的话)。因为不会创建 MainPage!无论如何,您的应用程序的每个页面都必须能够初始化整个应用程序,因为您必须支持从tombstoned state恢复。

    如有需要,请随时询问详情。

    【讨论】:

      【解决方案2】:

      否则你可以使用NavigationService.Navigate(homepageUri)

      【讨论】:

      • 我不想使用它,因为它可能会在我的应用程序导航堆栈中的某处导致不必要的循环。我编辑了我的原始帖子以更准确地反映我的问题。
      【解决方案3】:

      为什么要取消导航?只需删除OnBackKeyPress。在这种情况下您不需要它。

      【讨论】:

      • 我有 OnBackKeyPress 以防页面从我的应用程序中导航到,但在从活动磁贴导航到的情况下,我不确定如何以用户身份返回到开始屏幕会期待吗?我在原始帖子中添加了更多内容,也许这会有所帮助?
      【解决方案4】:

      创建一个变量来跟踪到主页的导航是否来自通过辅助磁贴的导航。在 MainPage.Load 检查该变量,如果变量来自辅助磁贴,则从后堆栈中删除前一页。从主页返回开始菜单而不是通过辅助磁贴页面返回是有意义的。这就是 MyStocks Portfolio(不,不是我的应用程序之一,而是我的应用程序之一

      这是一个关于后退按钮使用的好博客: http://blogs.msdn.com/b/ptorr/archive/2011/10/06/back-means-back-not-forwards-not-sideways-but-back.aspx

      【讨论】:

      • 我在上面编辑了我的解决方案,以更准确地展示我的实现和上面的问题。也许这会让您更深入地了解如何纠正问题?
      猜你喜欢
      • 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
      相关资源
      最近更新 更多