zoukankan      html  css  js  c++  java
  • XAML学习笔记——Layout(三)

       本篇随笔将介绍两种常见的布局——StackPanel和RelativePanel

      StackPanel

       StackPanel是一种应用很广的布局方式,无论在WPF还是在UWP当中,其中的子元素按照“栈”的结构排成一列(简单理解就是一个挨着一个的站成一排),其中子元素的排列方向根据Orientation值不同,可以分为水平方向(Horizontal)排列和竖直方向(Vertical)排列,默认是按照竖直方向排列。其中竖直方向排列比较典型的例子就是作为各种形式的列表(list)、组合框(ComboBox)、列表框(ListBox)还有一些菜单(Menu)中元素的布局方式,举个简单的例子(UWP版):

     1 <StackPanel Margin="50" 
     2                 Padding="10" 
     3                 HorizontalAlignment="Center" 
     4                 BorderBrush="BlueViolet" 
     5                 BorderThickness="3" 
     6                 CornerRadius="10">
     7         <TextBlock Margin="10" FontSize="20">How do you like your coffee?</TextBlock>
     8         <Button Margin="10" HorizontalAlignment="Stretch">Black</Button>
     9         <Button Margin="10" HorizontalAlignment="Stretch">With milk</Button>
    10         <Button Margin="10" HorizontalAlignment="Stretch">Latte machiato</Button>
    11         <Button Margin="10" HorizontalAlignment="Stretch">Chappuchino</Button>
    12     </StackPanel>

      效果如下:

    Tip :

      从UWP开始,StackPanel定义了新的border属性,可以直接用相关属性为StackPanel添加边框。这些属性主要包括:

      上面的例子就用上述属性为StackPanel添加了一个“华丽”的外边框。上述例子展示了元素的竖直排列方式,我们也可以让布局元素按照水平方向排列在StackPanel中,水平方向排列比较常见的例子有窗口的“确认”、“取消”按钮,表单下面的“提交”、“取消”按钮等。再举个水平方向的简单例子:

     

    1 <StackPanel Margin="8" 
    2                 HorizontalAlignment="Center" 
    3                 Orientation="Horizontal">
    4         <Button MinWidth="93">发布随笔</Button>
    5         <Button MinWidth="93" Margin="10,0,0,0">保存随笔</Button>
    6         <Button MinWidth="93" Margin="10,0,0,0">退出</Button>
    7     </StackPanel>

      所有的功能button按照水平居中方式排成一行:


      StackPanel中子元素的排列方式从语义方面体现出子元素间的并列关系,所以开发中如果遇到若干并列关系元素的布局,可以考虑用StackPanel。如果想要调整布局元素在StackPanel中的位置时可以使用Margin属性。同时,使用StackPanel时还需要特别注意一点:

    • 当子元素按照竖直方向排列时,子元素的VerticalAlignment值固定为Stretch。
    • 当元素按照水平方向排列的时候,子元素的HorizontalAlignment值同样固定为Stretch。

      在这两种情况下,想要调整元素在布局容器中的位置只能通过调节Margin属性。这种“特性”决定了StackPanel中一般不会嵌套其他布局方式(否则会出现某些怪异现象)。

      StackPanel从理论方面和实践方面都很好理解,暂且介绍到这里。。

       RelativePanel

      在以上介绍的三种布局中,子元素都是有一定规律性的排列在布局容器中,而RelativePanel则改变这种预定格式的布局方式,其中的子元素可在布局元素中随意排列,功能强大,用法灵活,而且RelativePanel是“响应式布局”实现的关键布局之一。想要理解RelativePanel就要理解其中“相对(Relative)“一词的含义,之所以称之为”相对“,就意味着子元素的位置一定与“相对目标”有关,按照“相对目标”的不同可以将RelativePanel中的布局属性分为以下两大类:

      相对“布局容器”位置关系属性

         在默认的情况下,RelativePanel布局容器中的子元素会在布局容器的(0,0)坐标点即左上角排列,我们可以通过为布局元素添加RelativePanel.AlignxxxWithPanel系列属性,来指明了子元素相对于布局容器的位置(上、下、左、右),主要包括:

    属性

    描述

    AlignBottomWithPanel

    当值为“True”时,元素位于布局容器底部并与底边对齐

    AlignTopWithPanel

    当值为“True”时,元素位于布局容器顶部并与上边对齐

    AlignLeftWithPanel

    当值为“True”时,元素位于布局容器左侧并与左边界对齐

    AlignRightWithPanel

    当值为“True”时,元素位于布局容器顶部并与右边界对齐

       例:

     1 <RelativePanel BorderBrush="BlueViolet" BorderThickness="2" Margin="10">
     2         <RelativePanel.Resources>
     3             <Style TargetType="Button">
     4                 <Setter Property="FontSize"
     5                            Value="25"/>
     6             </Style>
     7         </RelativePanel.Resources>
     8 
     9         <Button Content="TopLeft" Background="CadetBlue" 
    10                 RelativePanel.AlignTopWithPanel="True"
    11                 RelativePanel.AlignLeftWithPanel="True"
    12                 MinHeight="100" MinWidth="100"/>
    13         <Button Content="BottomLeft" Background="DeepSkyBlue" 
    14                 RelativePanel.AlignBottomWithPanel="True" 
    15                 RelativePanel.AlignLeftWithPanel="True"
    16                 MinHeight="100" MinWidth="100"/>
    17         <Button Content="TopRight" Background="RoyalBlue" 
    18                 RelativePanel.AlignRightWithPanel="True" 
    19                 RelativePanel.AlignTopWithPanel="True"
    20                 MinHeight="100" MinWidth="100"/>
    21         <Button Content="BottomRight" Background="LightBlue"  
    22                 RelativePanel.AlignBottomWithPanel="True"
    23                 RelativePanel.AlignRightWithPanel="True"           
    24                 MinHeight="100" MinWidth="100"/>
    25     </RelativePanel>

      效果:

      通过对四个button相对于布局容器位置属性的赋值,将它们放到了布局容器的四角。通过这类属性赋值的元素会严格按照边界对齐,如果要想实现居中效果就要借助于“相对布局面板居中”属性:

    属性 

    描述

    AlignHorizontalCenterWithPanel

    水平居中对齐于布局容器

    AlignVerticalCenterWithPanel

    竖直居中对齐于布局容器

       将以上的居中属性和上面的例子结合,可以使布局元素的位置更加多样:

     1     <RelativePanel BorderBrush="BlueViolet" BorderThickness="2" Margin="10">
     2         <RelativePanel.Resources>
     3             <Style TargetType="Button">
     4                 <Setter Property="FontSize"
     5                            Value="25"/>
     6             </Style>
     7         </RelativePanel.Resources>
     8 
     9         <Button Content="Top" Background="CadetBlue" 
    10                 RelativePanel.AlignTopWithPanel="True"
    11                 RelativePanel.AlignHorizontalCenterWithPanel="True"
    12                 MinHeight="100" MinWidth="100"/>
    13         <Button Content="Bottom" Background="DeepSkyBlue" 
    14                 RelativePanel.AlignHorizontalCenterWithPanel="True" 
    15                 RelativePanel.AlignBottomWithPanel="True" 
    16                 MinHeight="100" MinWidth="100"/>
    17         <Button Content="Right" Background="RoyalBlue" 
    18                 RelativePanel.AlignVerticalCenterWithPanel="True" 
    19                 RelativePanel.AlignRightWithPanel="True" 
    20                 MinHeight="100" MinWidth="100"/>
    21         <Button Content="Left" Background="LightBlue"  
    22                 RelativePanel.AlignVerticalCenterWithPanel="True" 
    23                 RelativePanel.AlignLeftWithPanel="True" 
    24                 MinHeight="100" MinWidth="100"/>
    25         <Button Content="Center" Background="Blue"  
    26                 RelativePanel.AlignVerticalCenterWithPanel="True" 
    27                 RelativePanel.AlignHorizontalCenterWithPanel="True" 
    28                 MinHeight="100" MinWidth="100"/>
    29     </RelativePanel>

      效果:

     

       相较于以前只能通过HorizontalAlignmentVerticalAlignmentMargin调节元素在布局容器中相对位置的方式,RelativePanel的这种方式显得灵活许多。实际上,在RelativePanel中还包括另一系列改变元素在布局容器中位置的属性:相对“目标元素”位置关系属性。

      相对“目标元素”位置关系属性

      第一次接触这一系列属性的最先想到的是我WP上的动态磁贴,于是乎自己动手模拟了一个例子:

     

      用这个呆萌的例子能很容易解释这一系列属性。拿FaceBook按钮为例,如果选择目标元素为WeiXin,那我们可以说它位于WeiXin下方并且和WeiXin左对齐;如果选择目标元素为Sina,则它位于Sina上方并且与Sina右对齐;若目标元素为QQ,则它位于QQ下方并与其右对齐。由此可见,相对“目标元素”位置关系属性可分为两大类:对齐关系和相对位置关系。

      对齐关系

      我们可以通过为布局元素添加RelativePanel.AlignxxxxWith系列属性,来指明子元素与目标元素的对齐方式,属性的值即为目标元素的x:Name值。这一系列属性主要包括:

    属性 描述
    AlignBottomWith 对齐于目标元素的下边界
    AlignTopWith 对齐于目标元素的上边界
    AlignLeftWith 左对齐于目标元素
    AlignRightWith 右对齐于目标元素

      相对位置关系

      通过为布局元素指定RelativePanel.xxx系列属性,可以说明布局元素与目标元素的相对位置关系,这一系列属性主要包括:

    属性 描述
    Above 在目标元素的上方
    Below 在目标元素的下方
    LeftOf 在目标元素的左边
    RightOf 在目标元素的右边

      由上面介绍的一大系列属性和例子可以看出RelativePanel布局方式多样化,同一种布局往往可以通过很多中方式实现,正因如此,在使用过程中有可能遇到如下问题:

      循环依赖

      举一个简单的例子,在布局过程中如果指定:“A元素在B元素的上方,B元素在A元素的下方”,这种布局链中所有的元素位置都不固定的情况,就形成了循环依赖,此时在XAML设计器中会得到编译时异常:"RelativePanel error: Circular dependency detected. Layout could not complete." 这就要求我们在布局过程中选择目标元素时保证其位置固定,进而避免产生元素间的循环依赖。

      关系冲突

       从上面介绍的一“大系列”属性和例子中可以看出,RelativePanel布局十分灵活,但同样有可能引起关系冲突,比如指定A元素在B元素左边同时又和B元素右对齐,这样两条布局规则不能同时成立的话,就要通过指定优先级来决定到底一哪一条规则为准。这种优先级顺序即为本篇随笔介绍先关属性的顺序:

     Tip:

      一般来讲,“相对布局面板居中”属性(AlignVerticalCenterWith, AlignHorizontalCenterWithPanel) 应用相对独立,并不会与其他属性发生冲突。

      在学习RelativePanel的过程中,我一直有一个疑问,传统的位置关系属性 HorizontalAlignment 和 VerticalAlignment 会起什么作用?查询官方资料得知这两个属性的优先级最低,即有其他关系属性存在的情况下就会忽略这两个属性。但是我试了一下,就算没有其他位置属性存在,RelativePanel也一样会无视他俩。总之,这部分还是有待学习(在RelativePanel 中还是先用好相对应的布局属性吧。。)。。

       这片随笔断断续续写了好长时间,感觉不太连贯。。

      果然一篇随笔介绍两种布局篇幅有点大。。下篇准备只介绍一个——SplitView布局。

  • 相关阅读:
    文件读写
    使用HttpClient实现文件的上传下载
    TreeMap
    Linux的目录结构与文件权限
    Hibernate中get()和load()方法的区别
    Hibernate中openSession()与getCurrentSession()的区别与联系
    Hibernate核心类和接口
    Hibernate连接数据库
    Struts2中OGNL表达式的用法
    Struts2中Result的配置
  • 原文地址:https://www.cnblogs.com/shiliangvv/p/5124788.html
Copyright © 2011-2022 走看看