Windows Phone内置的MessageBox弹出窗口局限性太大,不能满足各种个性化的弹出窗口的需求,即使使用第三方的控件库也会有一些局限性,又或者封装的东西太多了,那么这时候就需要自己去根据自己的需求去自定义一个弹出窗口了。

  大概的原理就是使用Popup控件来实现弹出窗的效果,Popup控件可以把包含在其中的控件显示在最外面,从而可以把当前页面的控件都给盖住了,再加点半透明的效果,若隐若现的,一个弹窗就出来了。好吧,下面来看一下Demo。

  先看一下demo的结构。

  

  Generic.xaml

<
ResourceDictionary
    xmlns
=
"
http://schemas.microsoft.com/winfx/2006/xaml/presentation
"
    xmlns:x
=
"
http://schemas.microsoft.com/winfx/2006/xaml
"
    xmlns:
local
=
"
clr-namespace:MessageControl;assembly=MessageControl
"
    xmlns:d
=
"
http://schemas.microsoft.com/expression/blend/2008
"
    xmlns:mc
=
"
http://schemas.openxmlformats.org/markup-compatibility/2006
"
  
    mc:Ignorable
=
"
d
"
    
>
    
<
Style TargetType
=
"
local:MyMessage
"
>
        
<
Setter
Property
=
"
FontFamily
"
Value
=
"
{StaticResource PhoneFontFamilyNormal}
"
/>
        
<
Setter
Property
=
"
FontSize
"
Value
=
"
{StaticResource PhoneFontSizeNormal}
"
/>
        
<
Setter
Property
=
"
Foreground
"
Value
=
"
{StaticResource PhoneForegroundBrush}
"
/>
        
<
Setter
Property
=
"
Background
"
Value
=
"
Snow
"
/>
        
<
Setter
Property
=
"
Width
"
Value
=
"
480
"
/>
        
<
Setter
Property
=
"
Height
"
Value
=
"
800
"
/>
        
<
!
--
定义模板的Template
-->
        
<
Setter
Property
=
"
Template
"
>
            
<
Setter.Value
>
                
<
ControlTemplate TargetType
=
"
local:MyMessage
"
>
                    
<
Grid VerticalAlignment
=
"
Stretch
"
>
                        
<
Rectangle x:Name
=
"
backgroundRect
"
Grid.Row
=
"
0
"
Fill
=
"
Black
"
Opacity
=
"
0.7
"
/>
                        
<
Border
                            VerticalAlignment
=
"
Top
"
                            BorderThickness
=
"
3
"
                            BorderBrush
=
"
Black
"
>
                            
<
StackPanel Margin
=
"
0
"
>
                                
<
ContentPresenter x:Name
=
"
body
"
/>
                            
</
StackPanel
>
                        
</
Border
>
                    
</
Grid
>
                
</
ControlTemplate
>
            
</
Setter.Value
>
        
</
Setter
>
    
</
Style
>
</
ResourceDictionary
>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
using Microsoft.Phone.Controls;
namespace MessageControl
{
    
public
class MyMessage : ContentControl
    {
        
private
System.Windows.Controls.ContentPresenter body;
        
private
System.Windows.Shapes.Rectangle backgroundRect;
        
private
object
content;
        
public
MyMessage()
        {
            
//
这将类的styleKey设置为MyMessage,这样在模板中的style才能通过TargetType
=
"
local:MyMessage
"
与之相互绑定
            this.DefaultStyleKey
=
typeof(MyMessage);
        }
        
//
重写OnApplyTemplate()方法获取模板样式的子控件
        
public
override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.body
=
this.GetTemplateChild(
"
body
"
)
as
ContentPresenter;
            this.backgroundRect
=
this.GetTemplateChild(
"
backgroundRect
"
)
as
Rectangle;
            InitializeMessagePrompt();
        }
        
//
使用Popup控件来制作弹窗
        internal Popup ChildWindowPopup
        {
            
get
;
            
private
set
;
        }
        
//
获取当前应用程序的UI框架PhoneApplicationFrame
        
private
static PhoneApplicationFrame RootVisual
        {
            
get
            {
                return Application.Current
==
null
?
null
: Application.Current.RootVisual
as
PhoneApplicationFrame;
            }
        }
        
//
弹窗的内容,定义为object,可以赋值为各种各样的控件
        
public
object
MessageContent
        {
            
get
            {
                return this.content;
            }
            
set
            {
                this.content
=
value;
            }
        }
        
//
隐藏弹窗
        
public
void Hide()
        {
            
if
(this.body !
=
null
)
            {
                
//
关闭Popup控件
                this.ChildWindowPopup.IsOpen
=
false
;
            }
        }
        
//
判断弹窗是否打开
        
public
bool IsOpen
        {
            
get
            {
                return ChildWindowPopup !
=
null
&&
ChildWindowPopup.IsOpen;
            }
        }
        
//
打开弹窗
        
public
void Show()
        {
            
if
(this.ChildWindowPopup
==
null
)
            {
                this.ChildWindowPopup
=
new
Popup();
                this.ChildWindowPopup.Child
=
this;
            }
            
if
(this.ChildWindowPopup !
=
null
&&
Application.Current.RootVisual !
=
null
)
            {
                InitializeMessagePrompt();
                this.ChildWindowPopup.IsOpen
=
true
;
            }
        }
        
//
初始化弹窗
        
private
void InitializeMessagePrompt()
        {
            
if
(this.body
==
null
)
                return;
            this.backgroundRect.Visibility
=
System.Windows.Visibility.Visible;
            
//
把模板中得body控件内容赋值为你传过来的控件
            this.body.Content
=
MessageContent;
            this.Height
=
800
;
        }
    }
}

  简单地创建有一个控件作为弹窗的内容,测试一下弹窗的效果,当然弹窗的控件你可以定义为你想要的各种内容。

  WindowsPhoneControl1.xaml

<
UserControl x:Class
=
"
TestMessageControl.WindowsPhoneControl1
"
    xmlns
=
"
http://schemas.microsoft.com/winfx/2006/xaml/presentation
"
    xmlns:x
=
"
http://schemas.microsoft.com/winfx/2006/xaml
"
    xmlns:d
=
"
http://schemas.microsoft.com/expression/blend/2008
"
    xmlns:mc
=
"
http://schemas.openxmlformats.org/markup-compatibility/2006
"
    mc:Ignorable
=
"
d
"
    FontFamily
=
"
{StaticResource PhoneFontFamilyNormal}
"
    FontSize
=
"
{StaticResource PhoneFontSizeNormal}
"
    Foreground
=
"
{StaticResource PhoneForegroundBrush}
"
    d:DesignHeight
=
"
250
"
d:DesignWidth
=
"
480
"
>
    
    
<
Grid x:Name
=
"
LayoutRoot
"
Background
=
"
LightBlue
"
>
        
<
Button Content
=
"
"
Height
=
"
72
"
HorizontalAlignment
=
"
Left
"
Margin
=
"
40,169,0,0
"
Name
=
"
button1
"
VerticalAlignment
=
"
Top
"
Width
=
"
160
"
/>
        
<
Button Content
=
"
关闭
"
Height
=
"
72
"
HorizontalAlignment
=
"
Left
"
Margin
=
"
254,169,0,0
"
Name
=
"
button2
"
VerticalAlignment
=
"
Top
"
Width
=
"
160
"
Click
=
"
button2_Click
"
/>
        
<
TextBlock Height
=
"
53
"
HorizontalAlignment
=
"
Left
"
Margin
=
"
54,72,0,0
"
Name
=
"
textBlock1
"
Text
=
"
《深入浅出Windows Phone 7应用开发》
"
VerticalAlignment
=
"
Top
"
Width
=
"
369
"
/>
    
</
Grid
>
</
UserControl
>
using System.Windows;
using System.Windows.Controls;
namespace TestMessageControl
{
    
public
partial class WindowsPhoneControl1 : UserControl
    {
        
public
WindowsPhoneControl1()
        {
            InitializeComponent();
        }
        
private
void button2_Click(
object
sender, RoutedEventArgs e)
        {
            (App.Current
as
App).myMessage.Hide();
        }
    }
}

  在App.xaml.cs中定义为全局弹窗

namespace TestMessageControl
{
    
public
partial class App : Application
    {
        ……
        
public
MyMessage myMessage
=
new
MyMessage { MessageContent
=
new
WindowsPhoneControl1() };
        ……
    }
}

  MainPage.xaml.cs

  单击事件

using Microsoft.Phone.Controls;
using MessageControl;
namespace TestMessageControl
{
    
public
partial class MainPage : PhoneApplicationPage
    {
        
public
MainPage()
        {
            InitializeComponent();
        }
        
private
void button1_Click(
object
sender, RoutedEventArgs e)
        {
            (App.Current
as
App).myMessage.Show();
        }
    }
}

  好了,来看一下运行的效果吧。