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布局。

原文地址:https://www.cnblogs.com/shiliangvv/p/5124788.html