[C#] Header Menu C# / XAML for Windows 8 Apps

用 C# / XAML 製作 Windows 8 Apps 的 Header Menu

如果有看過官網的人

 

應該就會知道

 

Header Menu 目前官網只提供 JavaScript / HTML 的程式碼範例

 

這幾天剛好用到

 

於是就把實作的方法寫下來

 

Header Menu 一開始我以為用內建的控制項 ComboBox 就可以完成了

 

但拉出來的樣子,就差了很多

 

IC582324官網的樣子

 

 

screenshot_10202012_181037_thumbComboBox 拉出來的樣子

 

 

所以,只好自己做新的控制項

 


 

首先,新增一個「使用者控制項(User Control)」並取名為「HeaderMenuControl.xaml」

 

image_thumb

 

 

程式碼如下


<UserControl
x:Class="HeaderMenu.HeaderMenuControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HeaderMenu"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="210"
d:DesignWidth="250">
<Grid >
<ListView BorderBrush="#FF99999A" Background="White" SelectionMode="None" BorderThickness="3" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListViewItem Foreground="#FF99999A" FontSize="24" Margin="0" Width="240">Collection</ListViewItem>
<ListViewItem Foreground="#FF99999A" FontSize="24" Margin="0" Width="240">Marketplace</ListViewItem>
<ListViewItem Foreground="#FF99999A" FontSize="24" Margin="0" Width="240">News</ListViewItem>
<ListViewItem Foreground="#FF99999A" FontSize="24" Margin="0" Width="240">Home</ListViewItem>
</ListView>
</Grid>
</UserControl>

將高度設為 180,寬度 設為 300

 

在內容的部分則插入一個「ListView」

 

並且新增幾個「ListViewItem」

 

做到這裡,其實就已經可以使用了

 

但按了之後,本身是沒有功能的,之後會再來說

 


 

回到原來主頁面

 

做一個「Header Title」

 

<Page
x:Class="HeaderMenu.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HeaderMenu"
xmlns:common="using:HeaderMenu.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="backButton" Grid.Column="0" Style="{StaticResource BackButtonStyle}"/>
<HyperlinkButton x:Name="pageTitle" Grid.Column="1" Content="Music ˅" FontSize="48" FontWeight="Normal" Margin="0,38,0,23" Click="pageTitle_Click_1" Foreground="#FF737375"/>
</Grid>
</Page>
view raw MainPage.xaml hosted with ❤ by GitHub

 

加入一個「Back」的「Button」

 

而這邊我們改使用 「HyperlinkButton」

 

讓滑鼠移過去或做點擊的時候有畫面上的回饋

 

並且我們在這個控制項上新增一個「Click」的事件

 

完成後

 

進到程式碼頁碼,也就是

 

MainPage.xaml

 

public sealed partial class MainPage : Page
{
public Popup headerMenuPopup;
// 自訂的控制項
public HeaderMenuControl headerMenuCtl;
// 是否已加入到 Popup 物件中
public bool isAddedToPopup;
public MainPage()
{
this.InitializeComponent();
// 初始化自訂控制項,並給予寬度和高度的初始值(和在控制項的設定為一樣的值)
this.headerMenuCtl = new HeaderMenuControl() { Width = 250, Height = 210 };
this.isAddedToPopup = false;
}
public static Popup ShowPopup(FrameworkElement source, UserControl control)
{
// 宣告一個 Popup 物件
Popup flyout = new Popup();
var windowBounds = Window.Current.Bounds;
var rootVisual = Window.Current.Content;
GeneralTransform gt = source.TransformToVisual(rootVisual);
// 設定絕對位置的原點從 (0, 0) 開始算
var absolutePosition = gt.TransformPoint(new Point(0, 0));
control.Measure(new Size(Double.PositiveInfinity, double.PositiveInfinity));
// 設定 Menu 要顯示的位置
flyout.VerticalOffset = absolutePosition.Y + source.ActualHeight;
flyout.HorizontalOffset = absolutePosition.X;
flyout.IsLightDismissEnabled = true;
// 將我們自訂的控制項加到此 Popup 物件中
flyout.Child = control;
// 設定 Menu 出現的動畫效果
var transitions = new TransitionCollection();
transitions.Add(new PopupThemeTransition() { FromHorizontalOffset = 0, FromVerticalOffset = -50 });
flyout.ChildTransitions = transitions;
return flyout;
}
private void pageTitle_Click_1(object sender, RoutedEventArgs e)
{
// 若是第一次按,則將物件新增到 Popup 物件裡。
if (!this.isAddedToPopup)
{
this.headerMenuPopup = ShowPopup(this.pageTitle, this.headerMenuCtl);
this.isAddedToPopup = true;
}
// 顯示 Popup
this.headerMenuPopup.IsOpen = true;
}
/// <summary>
/// 在此頁面即將離開時叫用。
/// </summary>
/// <param name="e">描述在離開頁面後要執行的事件資料。
/// Parameter 屬性通常用來設定頁面。</param>
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
}
}

 

宣告一個我們剛才做的控制項物件到此類別中

 

我們在這個類別裡建立一個靜態函式 「ShowPopup」

 

事實上,他只會在第一次點到「Header」的時候執行

 

並將做好的一個 Popup 物件,回傳回來到我們在類別中宣告的一個 Popup 物件

 

執行後的結果如下:

 

image_thumb1

 

 

然後你會發現一個問題

 

當我點選單中的選項時

 

選單並不會消失

 

為了解決這個問題

 

我們在呼叫 ShowPopup 之後

 

替 headerMenuCtl 建立一個「Tapped」的事件

 

當使用者點到控制項的任一位置時便會觸發此事件

private void pageTitle_Click_1(object sender, RoutedEventArgs e)
{
// 若是第一次按,則將物件新增到 Popup 物件裡。
if (!this.isAddedToPopup)
{
this.headerMenuPopup = ShowPopup(this.pageTitle, this.headerMenuCtl);
this.headerMenuCtl.Tapped += headerMenuCtl_Tapped;
this.isAddedToPopup = true;
}
// 顯示 Popup
this.headerMenuPopup.IsOpen = true;
}
void headerMenuCtl_Tapped(object sender, TappedRoutedEventArgs e)
{
this.headerMenuPopup.IsOpen = false;
}