不知道有人注意过Win10中的设置页面的布局没?那个页面会根据不一样的窗口宽度来调节显示的内容,甚至来后退按钮的操做在不一样的宽度也是不一样的,看图:ide
是否是有点cool呢,这篇文章,咱们就来作一个相似的布局。布局
首先将咱们须要展现出来的东西都添加到页面上,页面以下:测试
1 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 2 <Grid.RowDefinitions> 3 <RowDefinition Height="30"></RowDefinition> 4 <RowDefinition Height="*"></RowDefinition> 5 </Grid.RowDefinitions> 6 7 <!--大标题,后退按钮--> 8 <StackPanel Grid.Row="0" Orientation="Horizontal" x:Name="fullPanel"> 9 <Button Content="Back" x:Name="full_back" Click="full_back_Click"></Button> 10 <TextBlock Margin="10, 0, 0, 0">这是一个大标题</TextBlock> 11 </StackPanel> 12 13 14 <!--副标题,后退按钮,只在desktop上宽度小于500时显示--> 15 <StackPanel Grid.Row="0" Orientation="Horizontal" x:Name="detailPanel" > 16 <Button x:Name="detail_back" Content="Back" Click="detail_back_Click"></Button> 17 <TextBlock Margin="10, 0, 0, 0">这是一个副标题</TextBlock> 18 </StackPanel> 19 20 <!--内容--> 21 <RelativePanel Grid.Row="1"> 22 <!--左半部分的list--> 23 <ListView x:Name="left" IsItemClickEnabled="True" ItemClick="left_ItemClick" SelectedIndex="-1"> 24 <ListView.ItemTemplate> 25 <DataTemplate> 26 <StackPanel Margin="10"> 27 <TextBlock> 28 <Run Text="Item: "></Run> 29 <Run Text="{Binding}"></Run> 30 </TextBlock> 31 </StackPanel> 32 </DataTemplate> 33 </ListView.ItemTemplate> 34 </ListView> 35 36 <!--右半部份的详细信息--> 37 <Grid x:Name="right" > 38 <StackPanel> 39 <TextBlock>队长,别开枪。。</TextBlock> 40 <TextBlock > 41 <Run Text="Item:"></Run> 42 <Run Text="{Binding SelectedItem, ElementName=left}" Foreground="Red"></Run> 43 </TextBlock> 44 </StackPanel> 45 </Grid> 46 </RelativePanel> 47 </Grid>
后台绑定测试数据:this
1 private void MainPage_Loaded(object sender, RoutedEventArgs e) 2 { 3 this.left.ItemsSource = Enumerable.Range(1, 10).ToList(); 4 }
运行起来看看效果,有点乱啊,不急,咱们慢慢调。spa
这个页面中,咱们准备在窗口宽度小于500时显示窄布局,大于500时显示宽布局,下面就是咱们的VisualState发挥做用的时候了。咱们先建立一个VisualStateGroup,只用来针对窗口大小来调整布局,暂时先忽略掉mobile,详细说明请看注释。code
1 <VisualStateManager.VisualStateGroups> 2 <!--这个group里的VisualState只针对窗口宽度调整布局,不涉及设备--> 3 <VisualStateGroup x:Name="windowSize"> 4 <!--宽屏设置--> 5 <VisualState x:Name="wide"> 6 <VisualState.StateTriggers> 7 <!--大于等于501就算宽屏了。。--> 8 <AdaptiveTrigger MinWindowWidth="501"></AdaptiveTrigger> 9 </VisualState.StateTriggers> 10 <VisualState.Setters> 11 <!--这里进行宽屏下的设置--> 12 <!--隐藏副标题--> 13 <Setter Target="detailPanel.Visibility" Value="Collapsed"></Setter> 14 15 <!--显示大标题,虽然大标题默认是显示的,可是由于咱们之后会经过code修改显示属性,因此这里要重置才行--> 16 <Setter Target="fullPanel.Visibility" Value="Visible"></Setter> 17 18 <!--显示右侧内容--> 19 <Setter Target="right.Visibility" Value="Visible"></Setter> 20 21 <!--宽屏时,右侧内容应该是在list的右侧--> 22 <Setter Target="right.(RelativePanel.RightOf)" Value="left"></Setter> 23 24 <!--显示左侧内容--> 25 <Setter Target="left.Visibility" Value="Visible"></Setter> 26 </VisualState.Setters> 27 </VisualState> 28 29 <!--窄屏设置--> 30 <VisualState x:Name="narrow"> 31 <VisualState.StateTriggers> 32 <!--0-500都是小窗口--> 33 <AdaptiveTrigger MinWindowWidth="0"></AdaptiveTrigger> 34 35 </VisualState.StateTriggers> 36 <VisualState.Setters> 37 <!--默认显示副标题--> 38 <Setter Target="detailPanel.Visibility" Value="Visible"></Setter> 39 40 <!--隐藏大标题,点击副标题的后退才显示--> 41 <Setter Target="fullPanel.Visibility" Value="Collapsed"></Setter> 42 43 <!--显示右侧内容,点击副标题后退以后隐藏--> 44 <Setter Target="right.Visibility" Value="Visible"></Setter> 45 46 <!--隐藏左侧内容--> 47 <Setter Target="left.Visibility" Value="Collapsed"></Setter> 48 </VisualState.Setters> 49 </VisualState> 50 </VisualStateGroup> 51 </VisualStateManager.VisualStateGroups>
运行起来看看是否是效果要好不少了呢,如今调整窗口的宽度,是否是有点意思了呢?blog
可是后退按钮仍是没有效果,这里咱们须要使用code去控制了,可是这个很简单,由于咱们在不一样的布局下,使用的是不一样的button,这样的好处是不须要用code去判断窗口状态。这里咱们只贴上后台代码,一样很简单。get
1 private void full_back_Click(object sender, RoutedEventArgs e) 2 { 3 // 对于咱们的页面来讲,full_back按钮是应该隐藏的,由于没有上一层页面 4 // 因此这里咱们忽略掉,可是按钮仍是留着,你能够本身来作个隐藏的逻辑 5 } 6 7 private void detail_back_Click(object sender, RoutedEventArgs e) 8 { 9 // 这里就是为何咱们在VisualState里从新设置属性的缘由 10 11 // 显示左侧的list 12 // 隐藏右侧内容 13 this.left.Visibility = Visibility.Visible; 14 this.right.Visibility = Visibility.Collapsed; 15 16 // 隐藏副标题 17 // 显示主标题 18 this.fullPanel.Visibility = Visibility.Visible; 19 this.detailPanel.Visibility = Visibility.Collapsed; 20 } 21 22 private void left_ItemClick(object sender, ItemClickEventArgs e) 23 { 24 // 这里咱们须要判断下,是否须要切换隐藏 25 if (this.ActualWidth <= 500) 26 { 27 // 显示左侧的list 28 // 隐藏右侧内容 29 this.left.Visibility = Visibility.Collapsed; 30 this.right.Visibility = Visibility.Visible; 31 32 // 隐藏副标题 33 // 显示主标题 34 this.fullPanel.Visibility = Visibility.Collapsed; 35 this.detailPanel.Visibility = Visibility.Visible; 36 } 37 }
到这里的话,咱们的这个页面的行为和设置已经有点像了!it
到这里咱们这个页面的基本功能就算是差很少了,而后来完善下细节(其实仍是有个小问题,状态的切换仍是和设置有些区别的)。 io
1. 窗口宽度大于500的时候,直接给他一个固定的宽度,让list能宽一些。
2. 窗口宽度小于500的时候,把list撑满整个页面。这里咱们须要说下RelativePanel的一个特性(应该是特性吧。。),它内部的控件是不会自动拉伸撑满内部空间的,即便你用了HorizontalAlignment/VerticalAlignment,连Grid都不行!!咱们须要使用RelativePanel.AlignXXXX这一系列属性,根据须要来拉伸。
在咱们的页面中,咱们须要在窄屏下上下左右都对齐,来撑满页面。
1 <!--拉伸左侧list,撑满页面--> 2 <Setter Target="left.(RelativePanel.AlignRightWithPanel)" Value="True"></Setter> 3 <Setter Target="left.(RelativePanel.AlignBottomWithPanel)" Value="True"></Setter> 4 <Setter Target="left.(RelativePanel.AlignLeftWithPanel)" Value="True"></Setter> 5 <Setter Target="left.(RelativePanel.AlignTopWithPanel)" Value="True"></Setter>
最后的效果!
这篇文章的例子只是一个很简单布局,若是你准备实现复杂一些的功能的话,能够考虑把右侧的Grid换成Frame,而后经过左侧的ListItem导航到不一样的页面,来显示不一样的内容。