源碼下載: http://yunpan.cn/cFwwrT4V5rHIM 访问密码 1b97
在上一篇博客中,我已經說明了為什麼要自己寫一個PageLoader。原因就是,Frame的GoBack只是簡單的重新加載一個頁面,並不會保存原來的頁面的狀態。
怎麼樣才能保存原來的頁面狀態呢?只要原來的Frame不刪除,不就可以保存原來的狀態了嗎?所以實現起來就簡單多了,每Navigate一個頁面,我們就生成一個Frame,添加到Grid中,當Back時,我們就把這個Frame刪除掉。這樣就可以達到我們的目的了。
為了保證我們新加的Frame一定顯示在最前面,所以我們可以強制把ZIndex++,即每添加一個Frame,它的ZIndex都遞增。
而且因為是用了Add、Delete,我們就可以系統主題動畫了。
public void Init (Grid root) { root_ = root; if (root_.ChildrenTransitions == null) { TransitionCollection trans = new TransitionCollection() { new AddDeleteThemeTransition() { } }; root_.ChildrenTransitions = trans; } else { root_.ChildrenTransitions.Add(new AddDeleteThemeTransition()); } }
PageLoader的源碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media.Animation; namespace NavigateProj { public class PageLoader { private class PageInfo { public Type PageType { get; set; } public Frame PageFrame { get; set; } public object PageParam{ get; set; } public bool Load() { return PageFrame.Navigate(PageType, PageParam); } } private static PageLoader self_ = null; private Grid root_ = null; private Stack<PageInfo> pages_ = new Stack<PageInfo>(); private int zindex_ = 1; private PageLoader() { } public static PageLoader Instance { get { if (self_ == null) { self_ = new PageLoader(); } return self_; } } public void Init (Grid root) { root_ = root; if (root_.ChildrenTransitions == null) { TransitionCollection trans = new TransitionCollection() { new AddDeleteThemeTransition() { } }; root_.ChildrenTransitions = trans; } else { root_.ChildrenTransitions.Add(new AddDeleteThemeTransition()); } } public bool LoadPage (Type pageType, object param = null) { if (root_ == null) return false; PageInfo newPageInfo = new PageInfo() { PageType = pageType, PageFrame = new Frame(), PageParam = param, }; // ZIndex 保證在最前面 Canvas.SetZIndex(newPageInfo.PageFrame, zindex_); if (!newPageInfo.Load()) { return false; } root_.Children.Add(newPageInfo.PageFrame); ++zindex_; pages_.Push(newPageInfo); return true; } public bool Back () { if (pages_.Count <= 1) return false; var page = pages_.Pop(); root_.Children.Remove(page.PageFrame); --zindex_; var currPage = pages_.Peek(); return true; } } }