1、建立自訂控制項
為了代碼易於管理,在這裡,我把彈出畫面定義為一個自訂控制項。也就是包含一個xaml檔案和相關的代碼檔案。如所示,如何建立自訂控制項:
選擇使用者控制項,輸入名稱就可以了。
是建立好的畫面
我將控制項檔案SearchFlayout存放在Flayouts檔案夾下。
在xaml檔案中添加如下代碼
<UserControl x:Class="DevDiv_AppBar.Flayouts.SearchFlayout" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:DevDiv_AppBar.Flayouts" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid> <Popup x:Name="SearchPopup" IsLightDismissEnabled="True" Width="350" Height="130" > <StackPanel Background="Black"> <Border Background="#85bd" BorderThickness="4"> <StackPanel> <StackPanel Orientation="Horizontal" Margin="10"> <TextBlock Text="請輸入搜尋內容:" VerticalAlignment="Center" Margin="0,0,10,0" /> <TextBox Name="searchDataBox" Height="40" Width="150" FontSize="20" /> </StackPanel> <Button Click="SearchButtonClick" HorizontalAlignment="Center" Margin="10">搜尋</Button> </StackPanel> </Border> </StackPanel> </Popup> </Grid></UserControl>
在代碼中,需要提醒的是Popup的屬性IsLightDismissEnabled="True"。這表示當使用者點擊或者觸控螢幕幕的任意位置,不包括Popup的位置,pop-up畫面是否消失。當把Popup用作彈出畫面時,這個屬性必須設定為True,因為這是才符合基本的彈出畫面(flyout)使用者體驗。
如所示,我們還可以在設計器中,看到自訂控制項長什麼樣
在上面的代碼中需要注意的是建立彈出畫面必須使用Popup控制項,至於Popup控制項裡面的內容就按需而定即可。我在這裡用了TextBlock、TextBox和Button三個控制項,當然還有一個StackPanel容器控制項。
這樣我們xaml檔案就基本寫完了。下面我們開始編寫控制項的C#代碼
2、編寫自訂控制項代碼
在這裡,自訂控制項中主要實現兩個功能:顯示控制項本身和響應控制項提供的相關使用者互動操作大家看下面兩個函數Show方法主要就是將自己顯示出來。SearchButtonClick是響應自訂控制項中的搜尋按鈕事件。
注意:在Show方法中有一行代碼如下,是用來計算當前彈出畫面需要顯示的位置,後面會有講解(由於目前的版本中微軟並沒有提供相關好的方法來擷取顯示的位置,所以需要自行計算,希望在windows 8正式版發布之後,能解決這個問題)
FlyoutHelper.ShowRelativeToAppBar(SearchPopup, page, appbar, button);
public void Show(Page page, AppBar appbar, Button button) { SearchPopup.IsOpen = true; FlyoutHelper.ShowRelativeToAppBar(SearchPopup, page, appbar, button); } private void SearchButtonClick(object sender, RoutedEventArgs e) { SearchPopup.IsOpen = false; }
3、定位彈出的控制項(畫面)
在這裡我建立了一個FlyoutHelper類,其中定義了一個靜態方法ShowRelativeToAppBar。這個方法計算出相關按鈕上顯示的Popup的正確位置,這樣做,需要傳入Popup控制項、包含AppBar的Page、AppBar控制項和被點擊的button按鈕。這個方法並不好,但這是我發現的可以獲得flyout準確位置的唯一方法。具體代碼如下:
namespace DevDiv_AppBar.Flayouts{ class FlyoutHelper { public static void ShowRelativeToAppBar(Popup popup, Page page, AppBar appbar, Button button) { Func<UIElement, UIElement, Point> getOffset = delegate(UIElement control1, UIElement control2) { return control1.TransformToVisual(control2).TransformPoint(new Point(0, 0)); }; Point popupOffset = getOffset(popup, page); Point buttonOffset = getOffset(button, page); popup.HorizontalOffset = buttonOffset.X - popupOffset.X - (popup.ActualWidth / 2) + (button.ActualWidth / 2); popup.VerticalOffset = getOffset(appbar, page).Y - popupOffset.Y - popup.ActualHeight; if (popupOffset.X + popup.HorizontalOffset + popup.ActualWidth > page.ActualWidth) { popup.HorizontalOffset = page.ActualWidth - popupOffset.X - popup.ActualWidth; } else if (popup.HorizontalOffset + popupOffset.X < 0) { popup.HorizontalOffset = -popupOffset.X; } } }}
代碼會將Popup定位在與其相關的AppBar按鈕的上方,如果Popup從螢幕的左側或右側消失那麼Popup將被重新置放,由於這代碼比較噁心,我就不細講了,希望在windows 8正式版發布之後,這個問題會得到解決。
4、在程式中使用彈出畫面
將剛剛定義的控制項添加到MainPage.xaml中,代碼如下所示。
這裡需要將名稱空間添加進來using:DevDiv_AppBar.Flayouts 這樣才能使用Flayouts中定義的控制項。
下面的代碼中,添加自訂控制項是這行代碼
<flyouts:SearchFlayout x:Name="SearchFlayout"/>
雖然這裡並不是馬上就顯示出彈出畫面,但是我們也需要把自訂控制項聲明為主程式布局的一部分。
<Page x:Class="DevDiv_AppBar.MainPage" IsTabStop="false" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:DevDiv_AppBar" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:flyouts="using:DevDiv_AppBar.Flayouts" mc:Ignorable="d"> <Grid Background ="PaleGoldenrod"> <Image HorizontalAlignment="Left" Height="200" Margin="495,215,0,0" VerticalAlignment="Top" Width="295" Source="Assets/icon.png"/> <flyouts:SearchFlayout x:Name="SearchFlayout"/> </Grid></Page>
5、顯示彈出畫面
現在代碼基本編寫完畢了,剩下的任務就是當使用者點擊AppBar上的搜尋按鈕時,將彈出畫面顯示出來即可。
我在MainPage.xaml.cs中添加如下代碼:
並將該方法與AppBar的搜尋按鈕Click事件關聯起來即可
private void AppBarButtonClick(object sender, RoutedEventArgs e){ if (e.OriginalSource == AppBarSearchButton) { SearchFlayout.Show(this, this.BottomAppBar, (Button)e.OriginalSource); }}
原文地址:破船哥;http://www.devdiv.com/_DevDiv%E5%8E%9F%E5%88%9B_Windows_8_Metro_App%E5%BC%80%E5%8F%91%E4%B9%8B%E5%BC%B9%E5%87%BA%E7%94%BB%E9%9D%A2_Flayouts_-thread-130867-1-1.html