基本的用法我們在教程前面的“頁面布局與基本導航”中已經(jīng)講過了,這里繼續(xù)補充關于應用欄的更多用法。
在之前的學習中,我們知道 Icon 屬性中有很多很多系統(tǒng)預定義,但也許這些還是不夠的,現(xiàn)在就來增加幾種用法。
字符集應用
<AppBarToggleButton Label="Sigma" Click="AppBarButton_Click">
<AppBarToggleButton.Icon>
<FontIcon Glyph="Σ"/>
</AppBarToggleButton.Icon>
</AppBarToggleButton>
關于更多字符集的應用請訪問維基百科。
我們也可以用路徑來繪制一個屬于自己的圖形哦,下面的圖形大概就是 9 點鐘的樣子啦。
<AppBarToggleButton Label="Time" Click="AppBarButton_Click">
<AppBarToggleButton.Icon>
<PathIcon Data="F1 M 20,20 21,1L 21,21L 8,21"/>
</AppBarToggleButton.Icon>
</AppBarToggleButton>
如何適應不同的分辨率這也是值得我們去解決的問題,畢竟不論是從 8 英寸的平板還是 25 英寸的臺式機,甚至還有 4 英寸至 7 英寸的手機,在應用欄按鈕太多而屏幕不夠大時,多余的按鈕該怎么辦呢?
默認情況下,應用欄圖標的寬度都是確定好的 100 像素哦。那么我們先來看兩張圖片好了,由于 Windows 10 是可以直接調整 Modern 應用的大小的(而不是 windows 8 那種只能全屏顯示),所以我直接拉伸 Modern 大小以模擬分辨率的概率啦。
<Page.BottomAppBar>
<AppBar x:Name="bottomAppBar" IsSticky="True">
<Grid>
<StackPanel x:Name="leftBottomAppBar"
Orientation="Horizontal">
<AppBarButton Label="Like" Icon="Like"/>
<AppBarButton Label="Dislike" Icon="Dislike"/>
<AppBarButton Label="Delete" Icon="Delete"/>
<AppBarButton Label="Download" Icon="Download"/>
<AppBarButton Label="Pin" Icon="Pin"/>
</StackPanel>
<StackPanel x:Name="rightBottomAppBar"
Orientation="Horizontal" HorizontalAlignment="Right">
<AppBarButton Label="Play" Icon="Play"/>
<AppBarButton Label="Pause" Icon="Pause"/>
<AppBarButton Label="Stop" Icon="Stop"/>
<AppBarButton Label="Previous" Icon="Previous"/>
<AppBarButton Label="Next" Icon="Next"/>
</StackPanel>
</Grid>
</AppBar>
</Page.BottomAppBar>
這里為了調試更加方便,所以使用了 IsSticky 屬性。AppBarButton 還有一個很重要的屬性喲,之前用不到,不過這里就是核心成員了呢,它就是 IsCompact。這個屬性可以讓應用欄按鈕只顯示圖標而不顯示文字,也就是 Label 啦。那么我們的工作就要圍繞這個屬性來展開了。
我們可以這樣假設,有一個函數(shù),它有一個布爾變量的參數(shù),參數(shù)為真的話呢,那么所有的這些 AppBarButton 的 IsCompact 屬性也為真。在以下這段代碼中,我們先將 bottomAppBar 的自對象選取為 root,這樣一來的話呢,如果應用中還有頂部的應用欄,就不會相互干擾啦。然后逐步取出 root 和 panel 中的自對象就好咯。
private void AppBarButtonCompact(bool isCompact)
{
Panel root = bottomAppBar.Content as Panel;
if(root!=null)
{
foreach(Panel panel in root.Children)
{
foreach (ICommandBarElement child in panel.Children)
{
child.IsCompact = isCompact;
}
}
}
}
接下來還需要判斷到底需不需要啟用 IsCompact,那這又是由什么決定的呢,既然前面提到是因為屏幕的分辨率,也就是所應用所占用的寬度會導致應用欄發(fā)生重疊,那么答案就毫無疑問了。看到下面的代碼相信大家都明白了,至于為何是寬度的界限在 1000 呢,那是因為有 10 個 AppBarButton,前面也說了它們的寬度是 100。(不帶 Label 的話呢,就只需要 60 像素啦。)
void AppSizeChanged(object sender, SizeChangedEventArgs e)
{
if (e.NewSize.Width != e.PreviousSize.Width)
{
if (e.NewSize.Width < 1000)
{
AppBarButtonCompact(true);
}
else
{
AppBarButtonCompact(false);
}
}
}
來張圖片以示搞定這個問題了吧。
但是像我這么鉆牛角尖的人,10 個 AppBarButton 用這種方式搞定了,那 20 個呢?我們就來演示一下,把之前 XAML 中的 AppBarButton 復制粘貼一番。如果是 2K、4K 的屏幕應對 20 個沒問題啊,但我這 1920X1080 的屏幕就放不下了。
那么這又有什么辦法可以解決的嗎?當然有啦,將這 20 個圖標切成 2 列就好啦。我們首先在 Grid 中添加一行。
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
再通過下面這張方式來調整它處于哪一行,以及在水平方向的右側還是左側。這里我將兩行都設置在右側啦。
leftBottomAppBar.SetValue(Grid.RowProperty, 1);
leftBottomAppBar.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Right);
當然了,這樣一來就可以放 40 個 AppBarButton 啦,如果縮小應用的大小的話為了容納更多還可以用 IsCompact 屬性呢。不過沒有哪個應用做成這樣吧。
另外呢,如果把應用欄設計成這樣的話。
<Page.BottomAppBar>
<AppBar x:Name="bottomAppBar" IsSticky="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" x:Name="leftBottomAppBar" Orientation="Horizontal" HorizontalAlignment="Left">
<AppBarButton Label="Like" Icon="Like"/>
<AppBarButton Label="Dislike" Icon="Dislike"/>
<AppBarButton Label="Delete" Icon="Delete"/>
<AppBarButton Label="Download" Icon="Download"/>
<AppBarButton Label="Pin" Icon="Pin"/>
</StackPanel>
<StackPanel Grid.Column="1" x:Name="rightBottomAppBar" Orientation="Horizontal" HorizontalAlignment="Right">
<AppBarButton Label="Play" Icon="Play"/>
<AppBarButton Label="Pause" Icon="Pause"/>
<AppBarButton Label="Stop" Icon="Stop"/>
<AppBarButton Label="Previous" Icon="Previous"/>
<AppBarButton Label="Next" Icon="Next"/>
</StackPanel>
</Grid>
</AppBar>
</Page.BottomAppBar>
那么對于 Windows 10,在拉伸的過程中,中間部分的控件就會慢慢消失啦。以下這張圖片呢,是我在拉伸到中間有2個控件剛好重疊的時候啦。至于把 AppBarButton 設計成這樣是好是壞大家自己決定咯,我反正覺得這樣不好呢。不過有意思的是,即便如此,它們彼此的 Click 事件還都是有效的噢,會區(qū)分左右兩部分,而不會疊在一起。
當然啦,這個的應用遠不是應用欄這么簡單喲,對于其他的前景,比如有兩個 TextBlock 在屏幕左右兩側,當應用把收縮變小之后也可以讓這個 TextBlock 疊成 2 層在屏幕的一邊。
我們都見過有菜單的應用欄按鈕對吧,這個的實現(xiàn)其實也挺簡單的。用 Flyout 屬性就好了。
<Page.BottomAppBar>
<CommandBar>
<AppBarButton Icon="Rotate" Label="Rotate">
<AppBarButton.Flyout>
<MenuFlyout>
<MenuFlyoutItem Text="Rotate 90" Click="MenuFlyoutItem_Click" Tag="Rotate90"/>
<MenuFlyoutItem Text="Rotate 180" Click="MenuFlyoutItem_Click" Tag="Rotate180"/>
<MenuFlyoutItem Text="Rotate 270" Click="MenuFlyoutItem_Click" Tag="Rotate270"/>
</MenuFlyout>
</AppBarButton.Flyout>
</AppBarButton>
</CommandBar>
</Page.BottomAppBar>
Tag 屬性,就相當于做一個標簽。下面這段代碼就讓 Flyout 菜單發(fā)揮作用了。
private void MenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
MenuFlyoutItem selectedItem = sender as MenuFlyoutItem;
if (selectedItem != null)
{
if (selectedItem.Tag.ToString() == "Rotate90")
{
DoRotate(90);
}
else if (selectedItem.Tag.ToString() == "Rotate180")
{
DoRotate(180);
}
else if (selectedItem.Tag.ToString() == "Rotate270")
{
DoRotate(270);
}
}
}
更多建議: