RelativePanel 也是 Win10 UWP 新增的控件,和上篇提到的 SplitView 一样在 UWP 的 UI 布局起到非常重要的作用。说句实在话,这货其实就是为了 UWP 的 Adaptive UI 而特意增加的,由于他的功能和 DockPanel 有相当的重叠,以至于 DockPanel 被从 Win10 SDK 中被撸掉了……太惨了……
为什么说 RelativePanel 可以替代 DockPanel ,我们可以先从几个比较重要的属性看起: AlignLeft WithPanel, Align RightWithPanel, Align TopWithPanel, Align BottomWithPanel 。这几个属性如果是 True 的话,看上去的效果分明就是原先的 DockPanel .Left,Right,Top,Bottom 。我们先来看原先可以用 DockPanel 实现的下图,采用 RelativePanel 是如何编写的:
<RelativePanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" > <Button x:Name="ButtonHamburger" FontFamily="{ThemeResource SymbolThemeFontFamily}" Content="" RelativePanel.AlignLeftWithPanel="True"></Button> <TextBlock Text="类别" RelativePanel.RightOf="ButtonHamburger" RelativePanel.AlignVerticalCenterWith="ButtonHamburger" Margin="10,0,0,0"></TextBlock> <Button FontFamily="{ThemeResource SymbolThemeFontFamily}" Content="" RelativePanel.LeftOf="ButtonAdd"/> <Button x:Name="ButtonAdd" FontFamily="{ThemeResource SymbolThemeFontFamily}" Content="" RelativePanel.AlignRightWithPanel="True"/> </RelativePanel>
RelativePanel 中共有三个 Button ,一个 TextBlock 。分别靠左右对齐,用到了 RelativePanel 的几个附加属性: AlignLeftWithPanel , RightOf , LeftOf , AlignRightWithPanel 。这里还有一点要注意一下, TextBlock 为了实现纵向的居中对齐,使用了 AlignVerticalCenterWith ,有兴趣的同学可以试一下,在 RelativePanel 里 Ve rticalAlignment 优先级较低,仅在空间不足以显示控件时才起到居中对齐的作用。
有的童鞋会说以上的效果即使用 Grid 也是可以实现的,话是没有错啦,但在 UWP 开发中, RelativePanel 一般都是要配合 AdaptiveTrigger 来实现自适应布局的,比如下面两张图对比:
在平板或者桌面模式,采用左右的菜单布局,而在手机则变成上下菜单布局,在 UWP 中实现这种动态变化的效果,完全可以通过纯 XAML 来实现:
<RelativePanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState > <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="401" /> </VisualState.StateTriggers> </VisualState> <VisualState > <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="0" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="RelativeNavigation.(RelativePanel.AlignTopWithPanel)" Value="False"></Setter> <Setter Target="RelativeNavigation.(RelativePanel.AlignRightWithPanel)" Value="True"></Setter> <Setter Target="ButtonHome.(RelativePanel.AlignTopWithPanel)" Value="False"></Setter> <Setter Target="ButtonHome.(RelativePanel.AlignLeftWithPanel)" Value="True"></Setter> <Setter Target="ButtonMessage.(RelativePanel.Below)" Value=""></Setter> <Setter Target="ButtonMessage.(RelativePanel.RightOf)" Value="ButtonHome"></Setter> <Setter Target="ButtonAdd.(RelativePanel.Below)" Value=""></Setter> <Setter Target="ButtonAdd.(RelativePanel.RightOf)" Value="ButtonMessage"></Setter> <Setter Target="ButtonFind.(RelativePanel.Below)" Value=""></Setter> <Setter Target="ButtonFind.(RelativePanel.RightOf)" Value="ButtonAdd"></Setter> <Setter Target="ButtonMe.(RelativePanel.Below)" Value=""></Setter> <Setter Target="ButtonMe.(RelativePanel.RightOf)" Value="ButtonFind"></Setter> <Setter Target="GridContent.(RelativePanel.AlignBottomWithPanel)" Value="False"></Setter> <Setter Target="GridContent.(RelativePanel.AlignLeftWithPanel)" Value="True"></Setter> <Setter Target="GridContent.(RelativePanel.AlignBottomWith)" Value="RelativeNavigation"></Setter> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <RelativePanel x:Name="RelativeNavigation" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignTopWithPanel="True" Background="LightGray"> <Button x:Name="ButtonHome" FontFamily="{ThemeResource SymbolThemeFontFamily}" Content="" RelativePanel.AlignTopWithPanel="True"/> <Button x:Name="ButtonMessage" FontFamily="{ThemeResource SymbolThemeFontFamily}" Content="" RelativePanel.Below="ButtonHome"/> <Button x:Name="ButtonFind" FontFamily="{ThemeResource SymbolThemeFontFamily}" Content="" RelativePanel.Below="ButtonMessage"/> <Button x:Name="ButtonMe" FontFamily="{ThemeResource SymbolThemeFontFamily}" Content="" RelativePanel.Below="ButtonFind"/> <Button x:Name="ButtonAdd" FontFamily="{ThemeResource SymbolThemeFontFamily}" Content="" Background="Orange" RelativePanel.Below="ButtonMe"/> </RelativePanel> <Grid x:Name="GridContent" RelativePanel.AlignRightWithPanel="True" RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignTopWithPanel="True" RelativePanel.RightOf="RelativeNavigation" > <TextBlock Text="我是一个水印" Foreground="LightGray" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock> </Grid> </RelativePanel>
看上去啰里啰唆写了一大堆,主要还是为了展示 RelativePanel 的用法,并不是最优的写法,如果能提供各位一丝丝的灵感,那俺就很满意了。