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 ;
}
}
}
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();
}
}
}
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() };
……
}
}
{
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();
}
}
}
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();
}
}
}
好了,来看一下运行的效果吧。
本文转自 wws5201985 51CTO博客,原文链接:http://blog.51cto.com/wws5201985/812709,如需转载请自行联系原作者