近日,在处理拆分页面时,snap_detail始终无法正常返回snap,经过一番摸索,总结如下:
页面状态管理主要有四种页面状态,全屏横向,竖屏,缩屏,满屏。然后拆分页面只是为了设计给缩屏和竖屏视图,让他们可以展示下一级页面状态,当点击列表时,会展示详细页面。
其实就是一个物理页面,在里面展示两个逻辑页面:一个列表,一个详细信息。
比如:
1.拉到缩屏时,进入
protected override string DetermineVisualState(ApplicationViewState viewState) { // Update the back button's enabled state when the view state changes var logicalPageBack = this.UsingLogicalPageNavigation(viewState) && this.itemListView.SelectedItem != null; var physicalPageBack = this.Frame != null && this.Frame.CanGoBack; this.DefaultViewModel["CanGoBack"] = logicalPageBack || physicalPageBack; // Determine visual states for landscape layouts based not on the view state, but // on the width of the window. This page has one layout that is appropriate for // 1366 virtual pixels or wider, and another for narrower displays or when a snapped // application reduces the horizontal space available to less than 1366. if (viewState == ApplicationViewState.Filled || viewState == ApplicationViewState.FullScreenLandscape) { var windowWidth = Window.Current.Bounds.Width; if (windowWidth >= 1366) return "FullScreenLandscapeOrWide"; return "FilledOrNarrow"; } // When in portrait or snapped start with the default visual state name, then add a // suffix when viewing details instead of the list var defaultStateName = base.DetermineVisualState(viewState); return logicalPageBack ? defaultStateName + "_Detail" : defaultStateName; }
然后进入,判断页面当前的状态
private bool UsingLogicalPageNavigation(ApplicationViewState? viewState = null) { if (viewState == null) viewState = ApplicationView.Value; return viewState == ApplicationViewState.FullScreenPortrait || viewState == ApplicationViewState.Snapped; }
由上可以判断出当的snap,但是这里重写后,判断后返回的字串是:snap_detail
然后回到layoutware.cs,从这里,可以看到视图管理器会定位到页面前端的视图设置,进行隐藏控件等
private void WindowSizeChanged(object sender, WindowSizeChangedEventArgs e) { this.InvalidateVisualState(); }
public void InvalidateVisualState() { if (this._layoutAwareControls != null) { string visualState = DetermineVisualState(ApplicationView.Value); foreach (var layoutAwareControl in this._layoutAwareControls) { VisualStateManager.GoToState(layoutAwareControl, visualState, false); } } }
当从snap_detail点击返回时,进入代码:
/// <summary> /// Invoked when the page's back button is pressed. /// </summary> /// <param name="sender">The back button instance.</param> /// <param name="e">Event data that describes how the back button was clicked.</param> protected override void GoBack(object sender, RoutedEventArgs e) { if (this.UsingLogicalPageNavigation() && itemListView.SelectedItem != null) { // When logical page navigation is in effect and there's a selected item that // item's details are currently displayed. Clearing the selection will return to // the item list. From the user's point of view this is a logical backward // navigation. this.itemListView.SelectedItem = null; } else { // When logical page navigation is not in effect, or when there is no selected // item, use the default back button behavior. base.GoBack(sender, e); } }
void ItemListView_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (this.UsingLogicalPageNavigation()) this.InvalidateVisualState(); }
进入InvalidateVisualState()再去判断当前状态,此时: string visualState = DetermineVisualState(ApplicationView.Value);
当listview.selectitem=null时,导致logicalPageBack=false,说明不再是逻辑页面的返回了,而是物理返回前一个页面,所以关键在这,对选中的item的判断,会直接左右是否逻辑返回。
而我当时由于缺少下面这个方法,所以无法实现逻辑返回
void ItemListView_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (this.UsingLogicalPageNavigation()) this.InvalidateVisualState(); }
protected override void GoBack(object sender, RoutedEventArgs e) { if (this.UsingLogicalPageNavigation() && itemListView.SelectedItem != null) { // When logical page navigation is in effect and there's a selected item that // item's details are currently displayed. Clearing the selection will return to // the item list. From the user's point of view this is a logical backward // navigation. this.itemListView.SelectedItem = null; } else { // When logical page navigation is not in effect, or when there is no selected // item, use the default back button behavior. base.GoBack(sender, e); } }
所以在Goback方法中只对this.itemListView.SelectedItem = null;
没有changed事件再去判断整个页面的状态去到何处,所以也出现了点Goback没反应的情况了。
当点击数下时,此时selectitem=null,就会直接去到返回方法,真正返回到前一页面
if (this.UsingLogicalPageNavigation() && itemListView.SelectedItem != null)
base.GoBack(sender, e);