• 用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             // 显示左侧的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         }

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

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

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

  • 相关阅读:
    Asp.net 后台添加CSS、JS、Meta标签(帮助类)
    Jquery 事件冒泡
    一个例子理解C#位移
    CodeSmith 创建Ado.Net自定义模版(四)
    .NET4.0下网站应用程序用UrlRewriter.dll重写无后缀路径 (在IIS7.5中的配置方法)
    用泛型的IEqualityComparer<T>接口去重复项
    Why MapReduce?
    SYN flood攻击介绍
    tmux使用方法详解
    理解Linux系统负荷
  • 原文地址:https://www.cnblogs.com/ms-uap/p/4528169.html
Copyright © 2020-2023  润新知