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(); } } }
好了,来看一下运行的效果吧。