Creating a Custom MessageBox for Windows Phone Applications

by Shawn 13. November 2011 00:40

UPDATE: After posting this blog I found out about the message box within the XNA framework. This does allow for custom button text which is what I was trying to accomplish. However, the user experience is different than what you get from the message boxes within the native phone applications (eg: deleting a text). With the native message boxes, the application bar disappears, but with the XNA message box, it gets greyed out. It’s the little things that matter. Also within the XNA framework you cannot add additional components to the message box. For example, you might want to add a “Do not show me this again” option within the message box.

While using a Windows Phone you get prompted every once in awhile by a message box. Custom Applications have them, even apps native to the phone has them. When deleting a text message or a contact you get a nice prompt asking you if you want to delete it. But there is something unique about these message boxes that separates them from the one that you and I get to have. The standard message box only allows for an “OK” and a “Cancel” button. The message boxes that are native to the phone have custom text. When you delete a text, you are prompted with buttons “delete” and “cancel”. Seeing as there is not a way to do this, you need to create your own. I’ve created a very simple sample that can be used.

The CustomMessageBox sample is based on the assumption that message boxes are “binary”. What I mean is that you get binary options, Yes/No, OK/Cancel, etc. So I’ve limited what is allowed to be a valid result.

   1: public enum CustomMessageBoxResult
   2: {
   3:     Yes, 
   4:     No,
   5:     // Not using this yet, but you could wire up to the back button of the phone to be a cancel
   6:     Cancel
   7: }

I don’t have the ability to have a Show method return the CustomMessageBoxResult so I’ll need an EventArg that will be used within an event.

   1: public class MessageBoxEventArgs : EventArgs
   2: {
   3:     public CustomMessageBoxResult Result { get; set; }
   4: }

The xaml is pretty straight forward. We need to "”block” the page the CustomMessageBox is for. To do this I made the control a grid so it will fill up everything. Then give it a background with an opacity that will block all clicks.

<Grid x:Class="Visual.Controls.MessageBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"             
             Margin="0">
    <Grid.Background>
        <SolidColorBrush Color="{StaticResource PhoneBackgroundColor}" Opacity=".5"/>
    </Grid.Background>
    <Grid x:Name="MessagePanel" Background="{StaticResource PhoneChromeBrush}"
          VerticalAlignment="Top" HorizontalAlignment="Stretch"
          toolkit:TiltEffect.IsTiltEnabled="True">
        <StackPanel Margin="12,12,12,18">
            <TextBlock x:Name="HeaderTextBlock" TextWrapping="Wrap"
                       Style="{StaticResource PhoneTextLargeStyle}"
                       FontFamily="{StaticResource PhoneFontFamilySemiBold}"
                       HorizontalAlignment="Left"/>
            <TextBlock x:Name="MessageTextBlock" TextWrapping="Wrap"
                       Style="{StaticResource PhoneTextNormalStyle}"
                       FontSize="{StaticResource PhoneFontSizeMedium}"
                       Margin="12,24,12,24"
                       HorizontalAlignment="Left"/>
            <Grid HorizontalAlignment="Stretch" Margin="0,6,0,0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Button x:Name="YesButton" Click="YesButton_Click"/>
                <Button x:Name="NoButton" Grid.Column="1" Click="NoButton_Click"/>
            </Grid>
        </StackPanel>
    </Grid>
</Grid>

The message box has really one basic function, to ask the user a question. To accomplish that one function, we need to do three things.

  1. The message box must be put into the application. (Show method)
  2. When the user answers the question, the message box needs to be removed from the application. (Remove method)
  3. The message box needs to tell the application what the user picked. (Closed event)
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
 
using Microsoft.Phone.Controls;
 
namespace Visual.Controls
{
    public partial class MessageBox : Grid
    {
        private PhoneApplicationPage _page;
 
        private MessageBox()
        {
            InitializeComponent();
        }
 
        public event EventHandler<MessageBoxEventArgs> Closed;
 
        protected virtual void OnClosed(MessageBoxResult result)
        {
            // need to unsubscribe from the backkeypress
            _page.BackKeyPress -= Page_BackKeyPress;
 
            var handler = this.Closed;
            if (handler != null)
            {
                handler(this, new MessageBoxEventArgs { Result = result });
            }
            Remove();
        }
 
        public static MessageBox Show(string message, string caption, string yesButtonText, string noButtonText = null)
        {
            MessageBox msgBox = new MessageBox();
            msgBox.HeaderTextBlock.Text = caption;
            msgBox.MessageTextBlock.Text = message;
            msgBox.YesButton.Content = yesButtonText;
            if (string.IsNullOrWhiteSpace(noButtonText))
            {
                msgBox.NoButton.Visibility = Visibility.Collapsed;
            }
            else
            {
                msgBox.NoButton.Content = noButtonText;
            }
            msgBox.Insert();
            return msgBox;
        }
 
        private void Insert()
        {
            // Make an assumption that this is within a phone application that is developed "normally"
            var frame = Application.Current.RootVisual as Microsoft.Phone.Controls.PhoneApplicationFrame;
            _page = frame.Content as PhoneApplicationPage;
            _page.BackKeyPress += Page_BackKeyPress;
 
            // assume the child is a Grid, span all of the rows
            var grid = System.Windows.Media.VisualTreeHelper.GetChild(_page, 0) as Grid;
            if (grid.RowDefinitions.Count > 0)
            {
                Grid.SetRowSpan(this, grid.RowDefinitions.Count);
            }
            grid.Children.Add(this);
 
            // Create a transition like the regular MessageBox
            SwivelTransition transitionIn = new SwivelTransition();
            transitionIn.Mode = SwivelTransitionMode.BackwardIn;
 
            // Transition only the MessagePanel
            ITransition transition = transitionIn.GetTransition(MessagePanel);
            transition.Completed += (s, e) => transition.Stop();
            transition.Begin();
 
            if (_page.ApplicationBar != null)
            {
                // Hide the app bar so they cannot open more message boxes
                _page.ApplicationBar.IsVisible = false;
            }
        }
 
        private void Remove()
        {
            var frame = Application.Current.RootVisual as Microsoft.Phone.Controls.PhoneApplicationFrame;
            var page = frame.Content as PhoneApplicationPage;
            var grid = System.Windows.Media.VisualTreeHelper.GetChild(page, 0) as Grid;
 
            // Create a transition like the regular MessageBox
            SwivelTransition transitionOut = new SwivelTransition();
            transitionOut.Mode = SwivelTransitionMode.BackwardOut;
 
            ITransition transition = transitionOut.GetTransition(MessagePanel);
            transition.Completed += (s, e) =>
                {
                    transition.Stop();
                    grid.Children.Remove(this);
                    if (page.ApplicationBar != null)
                    {
                        page.ApplicationBar.IsVisible = true;
                    }
                };
            transition.Begin();
        }
 
        private void Page_BackKeyPress(object sender, CancelEventArgs e)
        {
            OnClosed(MessageBoxResult.Cancel);
            e.Cancel = true;
        }
        
        private void YesButton_Click(object sender, RoutedEventArgs e)
        {
            OnClosed(MessageBoxResult.Yes);
        }
 
        private void NoButton_Click(object sender, RoutedEventArgs e)
        {
            OnClosed(MessageBoxResult.No);
        }
    }
 
}

Now you can show your message box like such:

   1: var msgBox = CustomMessageBox.Show("Do you like Windows Phone.", "Custom Prompt", "I <3 WP", "No Thanks");

And you get the following:

image

Tags:

Windows Phone

Comments (8) -

steve
steve United States
1/17/2012 2:22:16 PM #

thanks for this

Reply

windows wallpapers
windows wallpapers United States
2/5/2012 3:00:48 PM #

Excellent learn, I simply passed this onto a colleague who was doing a little analysis on that.

nice article….thanks

Reply

Limpard Dwear
Limpard Dwear United States
2/28/2012 2:02:51 AM #

I hope you never stop!  This is one of the best blogs Ive ever read.  Youve got some mad skill here, man.  I just hope that you dont lose your style because youre definitely one of the coolest bloggers out there.  Please keep it up because the internet needs someone like you spreading the word.

Reply

how to become a fashion designer
how to become a fashion designer Egypt
3/16/2012 8:03:24 PM #

I was very pleased to discover this page. I need to to thank you for your time just for this wonderful read!! I definitely enjoyed every part of it and I have you bookmarked to check out new stuff on your website.

Reply

fashion design sketches
fashion design sketches Egypt
3/18/2012 7:45:41 PM #

I'm pretty pleased to discover this website. I wanted to thank you for ones time just for this wonderful read!! I definitely enjoyed every little bit of it and I have you bookmarked to see new stuff on your web site.

Reply

kangliquan
kangliquan People's Republic of China
3/25/2012 10:27:36 PM #

very helpful post, thank you.

Reply

business directory
business directory United States
5/15/2012 5:30:22 PM #

Again, superb post. You know, I am very delighted I found this. I'll digg your blog post so my buddies can read this too!

Reply

Dmytro
Dmytro Ukraine
3/21/2013 7:44:16 AM #

Very helpful, thanks.

Reply

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading

About the author

Shawn KendrotShawn Kendrot is a Technical Lead at Telvent, specializing in GIS (ArcGIS) Desktop and Silverlight.

Month List

Page List

DISCLAIMER

The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.