Windows Phone 7 - 學習使用Popup Control
開發WP7時總是在Silverlight的使用範例與別人的網站中看到使用Popup Control的機會,尤其是像Progress Bar的使用,
通常就會配合PopupControl將Prograss Bar的圖示蓋在目前畫面之上,透過設定Opacity(不透明度)讓畫面可以半透明的
呈現用戶得知目前正在執行一些任務。或是Popup出特定的User Control,協助用戶操作與完成任務。
這樣的操作效果,在WP7其實也蠻常用的,一來可以省掉NavigationService移動畫面要重新走一次Navigation流程,
二來可以讓用戶直覺的操作內容。
但使用Popup Control就只有好處沒有需要改變的地方嗎?其實是有的,當Popup Control使用時,它是直接覆蓋在目前畫面
中的最上層,因此,在撰寫程式時就需要為了關閉這個Poup Control多做一些處理,例如:按下back鍵把PopupControl關閉。
接下來仔細介紹Popup Control類別提供的內容與相關開發重點:
〉Popup 類別:
它是覆蓋在現有 Silverlight 內容的上方來顯示內容,要注意需在 Silverlight 控制項的界限內。Popup類別通常用於暫時顯示
或快速完成的特定工作內容。因此,Popup類別中放罝的UIElement集合,建議是放置些重要(或必要)的控制項目,讓用戶可
直接了當的閱讀或輸入內容。
(a) Popup類別使用「Child屬性」放置要顯示的UIElement集合,然而要注意的是:「不可以放置已設定x:Name的UIElemet控制項」,
因為Popup類別是直接加上去畫面上,因此,可能發生視覺化樹狀結構中存在兩個名稱相同的項目,這將會出現Exception。
透過下圖來示意Popup類別加入至現有的樹狀結構為何:
(b) Popup類別是以左上角為依據加入內容,可配合VerticalOffset 和 HorizontalOffset二個屬性來操作。如下圖:
大概了解Popup類別大致上的用法之後,接下來介紹幾個在開發上常用的屬性:
(a) 常用屬性表:
名稱 | 描述 |
Child | 取得或設定快顯視窗中要裝載 (Host) 的內容。放置要呈現於Popup類別中的UIElement,通常會自訂UserControl來使用。 |
IsOpen | 取得或設定此快顯視窗目前是否顯示在螢幕上的值。true:代表顯示;false:代表取消。 |
DataContext | 在 FrameworkElement 參與資料繫結時取得或設定其資料內容。 |
Dispatcher | 取得與這個物件關聯的 Dispatcher。透過Application可以直接取得。 |
HorizontalOffset | 取得或設定 Silverlight 控制項左邊與快顯視窗左邊之間的距離。 |
VerticalOffset | 取得或設定 Silverlight 控制項的頂端與快顯視窗的頂端之間的距離。 |
RenderTransform | 取得或設定轉換資訊,該資訊會影響 UIElement 的呈現位置。支援識別目前Popup類別所在的實際Poisition。配合Point類別的使用,即可算出目前實際呈現的位置。 |
Opacity | 取得或設定物件的不透明度。使用Popup類別建議可以使用Opactiy讓呈現於畫面上的內容,隱約可以看到背後的內容,這樣可提供用戶比較容易理解現在要操作的內容。 |
上述整理的屬性表,是目前我在學習中最常用到的地方,透過IsOpen來決定內容是否要顯示,然而RenderTransform是比較常
看到的部分,不過它可以有效算出目前UIElement在整個Page中的Position。在下方有提供範例的使用方法。
(b) 重要方法/事件:
名稱 | 描述 |
UpdateLayout | 確認 UIElement 的所有子物件位置都已正確為配置而更新。常用於更新畫面中的內容。 |
CaptureMouse | 設定 UIElement 的滑鼠捕捉。如果需要針對用戶於操作上需要補捉Mouse事件,可以啟動該方法 |
ReleaseMouseCapture | 釋放 UIElement 的滑鼠捕捉的事件。與CaptureMouse是一組的。 |
AddHandler | 針對指定的路由事件加入路由事件處理常式,以便將該處理常式加入至目前項目上的事件處理常式集合。 將 handledEventsToo 指定為 true,以針對已經由事件路由上另一個項目標記為已處理的路由事件,叫用提供的處理常式。 |
RemoveHandler | 從這個 UIElement 移除指定的路由事件處理常式。 |
針對Handler的使用,下方的範例是直接另外自訂一個Handler來使用,其實如果需要增加Popup類別有額外自訂的Handler,
透過AddHandler與RemoveHandler一樣可以做到相同的效果,但要注意的是Delegate的使用。
〉範例說明 - 使用Popup Control模擬Dropdownlist:
透過一個TextBox加上一個自訂的User Control來完成模擬Dropdownlist的效果。觸發的事件在於:當用戶點擊TextBox後,
觸發GotFocus事件,彈出Popup Control的內容,選擇Popup中的內Listbox,並回傳至TextBox中。以下將透過程式來加以說明:
1. 自訂User Control.xaml:
1: <!-- 自訂User Control並放置一個ListBox -->
2: <UserControl x:Class="PopupControlPractice.CusControl.PageList"
3: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5: xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6: xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7: mc:Ignorable="d"
8: FontFamily="{StaticResource PhoneFontFamilyNormal}"
9: FontSize="{StaticResource PhoneFontSizeNormal}"
10: Foreground="{StaticResource PhoneForegroundBrush}"
11: d:DesignHeight="480" d:DesignWidth="480" Height="382">
12:
13: <StackPanel x:Name="LayoutRoot" Background="#FF473B3B" Opacity="0.795" HorizontalAlignment="Center" VerticalAlignment="Center" Height="350">
14: <ListBox Name="listBox1" Width="460" SelectionChanged="listBox1_SelectionChanged" Height="400">
15: <ListBoxItem Content="Taiwan" FontSize="36" />
16: <ListBoxItem Content="Taipei" FontSize="36" />
17: <ListBoxItem Content="Taichung" FontSize="36" />
18: <ListBoxItem Content="台灣" FontSize="36" />
19: <ListBoxItem Content="台北" FontSize="36" />
20: <ListBoxItem Content="高雄" FontSize="36" />
21: <ListBoxItem Content="台南" FontSize="36" />
22: <ListBoxItem Content="台中" FontSize="36" />
23: <ListBoxItem Content="新北" FontSize="36" />
24: </ListBox>
25: </StackPanel>
26: </UserControl>
2. 自訂User Control.cs:
1: public partial class PageList : UserControl
2: {
3: //Popup control類別
4: private Popup gPopupControl;
5: //獨立宣告一個SelectionChangedEventHandler事件
6: public event SelectionChangedEventHandler PageListSelectHandler;
7:
8: public PageList()
9: {
10: InitializeComponent();
11: }
12:
13: //該方法用於告知Popup Control要產生的Position
14: public void Create(double x, double y)
15: {
16: gPopupControl = new Popup();
17: gPopupControl.Child = this;
18:
19: gPopupControl.IsOpen = true;
20: //設定X與Y軸
21: gPopupControl.HorizontalOffset = x + 5;
22: gPopupControl.VerticalOffset = y + 25;
23: }
24:
25: private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
26: {
27: //當觸發選取事件後,將剛獨立宣告的SelectionChangedEventHandler事件往上層推送
28: SelectionChangedEventHandler tHandler = this.PageListSelectHandler;
29: if (tHandler != null)
30: tHandler.Invoke(sender, e);
31: gPopupControl.IsOpen = false;
32: }
33: }
3. 在主畫面中的TextBox加上GotFocus事件與接收SelectionChangedEventHandler事件的處理:
1: private void textBox1_GotFocus(object sender, RoutedEventArgs e)
2: {
3: //透過GeneralTransform取得目前TextBox的位置資訊
4: GeneralTransform tTransform = base.TransformToVisual(textBox1);
5: //轉換Transform為實際的Point
6: Point tPoint = tTransform.Transform(new Point(0.0, 0.0));
7: //宣告Popup Control類別
8: CusControl.PageList tList = new CusControl.PageList();
9: //設定Popup Control類別要出現的Position
10: tList.Create(textBox1.Margin.Left + Math.Abs(tPoint.X),
11: textBox1.Margin.Top + textBox1.Height + Math.Abs(tPoint.Y));
12: //註冊處理EventHandler
13: tList.PageListSelectHandler += new SelectionChangedEventHandler(tList_PageListSelectHandler);
14: }
15:
16: void tList_PageListSelectHandler(object sender, SelectionChangedEventArgs e)
17: {
18: ListBoxItem tObject = e.AddedItems[0] as ListBoxItem;
19:
20: textBox1.Text = tObject.Content.ToString();
21: }
4. 執行結果:
======
以上是介紹Popup Control類別的使用,讓在開發WP7時,針對一些比較只是提示型的內容,除了可以透過WP7的ContextMenu類別之外,
也提供另一種透過Popup Control達到的效果。不過透過Popup Control要特別注意產生Popup Control物件的情況,例如:產生完的物件要
如何關閉,要透過Back鍵還是Popup Control中自訂Button來關閉等,這些都會影響畫面中呈現與用戶操作的習慣。
References:
‧Creating a custom popup in Windows Phone 7
‧Windows Phone 7 Quick Tip #5 – Dismissing Popups Controls
‧Playing with the Popup Control (必看)
‧System.Windows.Controls.Primitives 命名空間
‧PopUp Control In Silverlight (必看)
‧Tutorial: Create a Silverlight 2 User Control from a Popup Control
‧Multiline textbox in Windows Phone 7
‧How to get screen size on Windows Phone 7 Series?
‧WP7 LongListSelector in depth | Part1: Visual structure and API & Part2 (補充)
‧Using the LongListSelector control on Windows Phone 7 (補充)
‧Rectangle in Silverlight & Draggable Popup Window in Silverlight 3
‧How to position popup control? (重要)