你的位置:首页 > ASP.net教程

[ASP.net教程]用UWP实现一个和win10设置页面类似的布局

不知道有人注意过Win10中的设置页面的布局没?那个页面会根据不同的窗口宽度来调节显示的内容,甚至来后退按钮的操作在不同的宽度也是不同的,看图:

 

是不是有点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>

后台绑定测试数据:

1     private void MainPage_Loaded(object sender, RoutedEventArgs e)2     {3       this.left.ItemsSource = Enumerable.Range(1, 10).ToList();4     }

运行起来看看效果,有点乱啊,不急,我们慢慢调。

这个页面中,我们准备在窗口宽度小于500时显示窄布局,大于500时显示宽布局,下面就是我们的VisualState发挥作用的时候了。我们先创建一个VisualStateGroup,只用来针对窗口大小来调整布局,暂时先忽略掉mobile,详细说明请看注释。

 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>

运行起来看看是不是效果要好很多了呢,现在调整窗口的宽度,是不是有点意思了呢?

但是后退按钮还是没有效果,这里我们需要使用code去控制了,但是这个很简单,因为我们在不同的布局下,使用的是不同的button,这样的好处是不需要用code去判断窗口状态。这里我们只贴上后台代码,同样很简单。

 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       // 显示左侧的list12       // 隐藏右侧内容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         // 显示左侧的list28         // 隐藏右侧内容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     }

到这里的话,我们的这个页面的行为和设置已经有点像了!

到这里我们这个页面的基本功能就算是差不多了,然后来完善下细节(其实还是有个小问题,状态的切换还是和设置有些区别的)。 

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导航到不同的页面,来显示不同的内容。