Windows 8 开发系列- 拆分页关键问题分析

近日,在处理拆分页面时,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);


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(windows)