WindowsPhone 7 定制控件 - 可重用的弹出框容器(PopupContainer)

徐新荣
2023-12-01


开发 WindowsPhone 7 应用程序时,我们经常需要弹出一个对话框(Popup Dialog)来向用户提示一些信息,或向用户索取输入信息。相比于完全导航(Navigate)到一个新的界面,半遮掩式的弹出窗口显得更加轻便(Lightweight),也提供更加紧凑的交互上下文环境(Interaction Context)。这一点尤其适用于那些些内容相对简单、控件数量相对较少的界面。然而,Windows Phone 7 SDK 中,并没有对弹出对话框提供太多的功能。最常用的也就是 MessageBox.Show() 而已。 

 

在这片文章里,我将介绍如何构建一个可重用的弹出框容器(PopupContainer)。首先来看一下运行效果:

  

下载示例代码

 

一些说明: 

       - 弹出框中的内容区域完全由开发者自定义,弹出框的高度自动适应。

       - 显示时由上至下滑落,关闭时由下至上回升。

       - 关闭弹出框的方式有三种:

            1. 点击弹出框中的 OK Cancel 按钮。

             2. 点击弹出框下灰蒙蒙的的遮罩(mask)区域。

             3. 按下 Windows Phone 7 的物理回退按钮(Back Key)。

       - 弹出框底部带有阴影效果,增加立体层次感。 

 

使用方法:

既然是可重用的功能,当然希望它的用法越简单越好。因此,我将弹出框的功能封装为一个容器,并接受任意一个用户控件(UserControl)做为其显示内容,并负责用弹出框的形式来显示和隐藏。在某个页面(例如:自动生成的 MainPage)的一个按钮点击事件中,只需要写下如下代码:

PopupCotainer pc = new PopupCotainer(this);

pc.Show(new UserControl1()); 

复制代码

上述代码中: 

1.  PopupContainer 就是本文所讨论的可重用的弹出框容器类。

2. 创建一个 PopupContainer 对象时,需要传递当前的页面对象(this),其目的是让它能够监听并响应 BackKeyPress 事件,关闭弹出框。

3. 调用 PopupContainer 对象的 Show() 方法,并传递一个用户控件,用弹出框的形式进行显示。UserControl1是一个用户控件(当然也可以是一个PhoneApplicationPage)。

 

为了给开发者提供尽可能大的自由度,PopupContainer 本身并不提供任何内置的 OK Cancel 之类的按钮,而是把这部分工作留给开发者自己去完成。那么,以上述代码为例,我们就需要在 UserControl1 中设置一两个按钮,并在其点击事件(Click Event)中,写下如下代码,以关闭弹出框:

private void OKButton_Click(object sender, RoutedEventArgs e)
{
    
this.CloseMeAsPopup();
}

复制代码

咦?CloseMeAsPopup()方法是哪里来的呢?默认的 UserControl 类中并不包含这样的方法啊?

没错!这个方法其实是 PopupContainer 提供的一个扩展方法(Extension Method)。有了这样的扩展方法,在一个用户控件中,关闭包含它的弹出框就只需要一行代码而已! 

 

怎么样,够简单吧?

如果你对如何实现这样一个 PopupContainer 感兴趣,并希望在此基础上进行扩展和改进,请继续阅读下面的具体说明。 

原理解析:

1. PopupContainer 是一个用户自定义控件。查看 PopupCotainer.xaml 文件内容,里面主要定义了三个元素:

       - contentArea:用于承载和显示弹出框里的具体内容。

       - mask:介于弹出框内容及底层页面之间的遮罩层。 

       - shadow:定义一个渐变色填充的矩形,作为弹出框的阴影区域。

2. PopupContainer 实际上是借助 Windows Phone 7 SDK 自带的 Popup 类来实现弹出框的功能。在实例代码项目中,查看 PopupCotainer.xaml.cs 文件中的 Show() 方法。Show() 方法创建 Popup 对象,并设置其 IsOpen 属性为 true。这一赋值过程会触发 PopupContainer 控件的 Loaded 事件(对应 PopupCotainer_Loaded() 方法)。在PopupCotainer_Loaded() 方法中进行弹出框的显示。  

3. 弹出框显示时由上至下滑落的效果,使用一段故事版动画(Storyboard Animation)。查看 PopupCotainer.xaml.cs 文件中的 PrepareShowStory() 方法。在该方法的入口处,将传递给它的内容控件植入到 contentArea中,并调用UpdateLayout() 方法,强制更新 UI,从而获得内容区域的真实高度,继而决定弹出框下落的幅度。

4. 关闭弹出框时弹回的效果,同样使用一段故事版动画(Storyboard Animation)。查看 PopupCotainer.xaml.cs 文件中的 PrepareCloseStory() 方法。不仅如此,在弹出框滑落过程中,用户点击遮罩层(mask)或后退按钮时,为了让弹出框的退回效果连贯,在该方法中,动态地设置了动画的起始值(查看 animation.From)。

5. PopupContainer 还注册监听触发页面的 BackKeyPress事件,以实现在用户点击物理回退按钮时,关闭自身。

6. PopupCotainer.xaml.cs 文件中还定义了一个 PopupManager 类,里面定义了一个扩展方法 CloseMeAsPopup(),用来提供在弹出框内容控件内部,关闭包含它的弹出框。(其调用示例可以查看 UserControl1.xaml.cs 文件中的 OKButton_Click()方法或 CancelButton_Click() 方法

 

OKPopupContainer的实现逻辑就介绍到这里,更具体的内容可以查看示例代码

 类似资料: