RelativePanel也是Win10 UWP新增的控件,和上篇提到的SplitView一樣在UWP的UI布局起到非常重要的作用。說句實在話,這貨其實就是為了UWP的Adaptive UI而特意增加的,由於他的功能和DockPanel有相當的重疊,以至於DockPanel被從Win10 SDK中被擼掉了……太慘了……
為什么說RelativePanel可以替代DockPanel,我們可以先從幾個比較重要的屬性看起:AlignLeftWithPanel,AlignRightWithPanel,AlignTopWithPanel,AlignBottomWithPanel。這幾個屬性如果是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里VerticalAlignment優先級較低,僅在空間不足以顯示控件時才起到居中對齊的作用。
有的童鞋會說以上的效果即使用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的用法,並不是最優的寫法,如果能提供各位一絲絲的靈感,那俺就很滿意了。