这节我们两个议题①在源代码中改变平铺②在xaml中改变平铺样式
(1)在源代码中改变平铺
这个平铺系统中最核心的是windows中的ViewStateChanged事件。为了处理事件,你可以重新配置的你的程序,来生成这个事件。下列是源代码所示:

using Windows.UI.ViewManagement; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace MetroGrocer.Pages { //DetailPage类 public sealed partial class DetailPage : Page { public DetailPage() { this.InitializeComponent(); // ViewStateChanged 事件 ApplicationView.GetForCurrentView().ViewStateChanged += (sender, args) => { HandleViewStateChange(args.ViewState); }; } //处理HandleViewStateChange事件 private void HandleViewStateChange(ApplicationViewState viewState) { if (viewState == ApplicationViewState.Snapped) { GridLayout.ColumnDefinitions[0].Width = GridLengthHelper.FromPixels(0); } else { GridLayout.ColumnDefinitions[0].Width = GridLengthHelper.FromValueAndType(1, GridUnitType.Star); } } } }
处理这个事件是传递这个ApplicationViewStateChangedEventArgs对象,他的Viewstate属性是来自于ApplicationViewState这个迭代器。描述这个当前平铺的对象。这个迭代器是抢购,填充,全屏水平模式和全屏风景模式。这两个模式允许看全屏模式的差异。
这个HandleViewStateChange事件是用来适应布局方式,如果这个app是在断裂模式下显示,我把第一行的宽度设置是0. 恢复全屏状态下,他的状态不能自动更新。你也需要用源代码处理状态。 这些状态是除了断裂状态。因此,我重置列的宽度。下图,你也可以看到断裂实现他们之间的状态的变化。
(2)在xaml中改变平铺样式
你可以在xaml中改变平铺样式,你也发现xaml语法是冗长。因此,他是很难阅读,他也很难处理,因此在真正的开发中,我也推荐你用插入code approach的方法、 但这里我用的是xaml,下图是xaml的源代码。
特别提醒,想什么VisualStateManager类别,是wpf中和silverlight中的标准的类,我这里没有提及,你要用心的学习较完全的xaml语言请看具体的wpf文档。
这里,源代码如下所示:
1 <Page 2 x:Class="MetroGrocer.Pages.DetailPage" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="using:MetroGrocer.Pages" 6 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 7 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 8 mc:Ignorable="d"> 9 <Grid x:Name="GridLayout" Background="#71C524"> 10 <VisualStateManager.VisualStateGroups> 11 <VisualStateGroup x:Name="OrientationStates"> 12 <VisualState x:Name="Snapped"> 13 <Storyboard> 14 <ObjectAnimationUsingKeyFrames 15 Storyboard.TargetProperty="Grid.ColumnDefinitions[0].Width" 16 Storyboard.TargetName="GridLayout"> 17 <DiscreteObjectKeyFrame KeyTime="0"> 18 <DiscreteObjectKeyFrame.Value> 19 <GridLength>0</GridLength> 20 </DiscreteObjectKeyFrame.Value> 21 </DiscreteObjectKeyFrame> 22 </ObjectAnimationUsingKeyFrames> 23 </Storyboard> 24 </VisualState> 25 <VisualState x:Name="Others"> 26 <Storyboard> 27 <ObjectAnimationUsingKeyFrames 28 Storyboard.TargetProperty="Grid.ColumnDefinitions[0].Width" 29 Storyboard.TargetName="GridLayout"> 30 <DiscreteObjectKeyFrame KeyTime="0"> 31 <DiscreteObjectKeyFrame.Value> 32 <GridLength>*</GridLength> 33 </DiscreteObjectKeyFrame.Value> 34 </DiscreteObjectKeyFrame> 35 </ObjectAnimationUsingKeyFrames> 36 </Storyboard> 37 </VisualState> 38 </VisualStateGroup> 39 </VisualStateManager.VisualStateGroups> 40 <Grid.RowDefinitions> 41 <RowDefinition/> 42 <RowDefinition/> 43 </Grid.RowDefinitions> 44 <Grid.ColumnDefinitions> 45 <ColumnDefinition/> 46 <ColumnDefinition/> 47 </Grid.ColumnDefinitions> 48 // …StackPanel elements removed for brevity… 49 </Grid> 50 </Page>
在上述的源代码中,我定义了两个VisualState状态,首先,我得把第一行的宽度置为0,这个状态是断裂视图状态。第二个状态,这是一个其他的视图的状态,这部分无论是xaml的源代码还是C#源代码都很冗长。
另外,我得处理ViewStateChanged事件,以至于他能进入xaml的状态,下列是处理的C#源代码
1 using Windows.UI.ViewManagement; 2 using Windows.UI.Xaml; 3 using Windows.UI.Xaml.Controls; 4 namespace MetroGrocer.Pages { 5 public sealed partial class DetailPage : Page { 6 public DetailPage() { 7 this.InitializeComponent(); 8 ApplicationView.GetForCurrentView().ViewStateChanged 9 += (sender, args) => { 10 string stateName = args.ViewState == 11 ApplicationViewState.Snapped ? "Snapped" : "Others"; 12 VisualStateManager.GoToState(this, stateName, false); 13 }; 14 } 15 } 16 }
我调用了静态的VisualStateManager.GoStates使其在xaml定义的状态能够互相切换。这个方法传递的参数是当前页面对象,这一位着你进入了这个状态以后,其中间状态不会显示,直接完成状态之间的切换。最后一个参数为真的时候,代表平铺状态自由切换的时候,能够提供其动画效果。
哝——这就是这节的议程。