You are on page 1of 8

12,572,730 members (58,492 online)

Sign in

Search for articles, questions, tips

articles

quick answers

discussions

community

help

Articles Platforms, Frameworks & Libraries Windows Presentation Foundation General

A Simple Way to Make a Custom WPF Message


Box
Steve Naidamast, 7 Oct 2016

CPOL

Rate this:

5.00 (1 vote)
Here is a simple way to make a custom WPF Message Box

Overview
In my last piece (A Simple Way to Make a WPF Chromeless Window), I demonstrated how one could easily create a
chromeless window using Microsofts Windows Foundation Framework, more commonly known as WPF. This time
around, I will show you how to make a customized WPF message box.
The reason for this is that the WPF default message box uses the same chrome that the default WPF window does. As a
result, if you are going to develop a custom window, you will also have to do the same with your message boxes or the
contrasts between the two will not look symmetrical.
And being deficient in the graphic arts like many software engineers, I found this out the hard way when my own
commercial product was well reviewed except for the interface. Hence, my recent work to refine the interface to
something much more aesthetically pleasing.

Limitations With Your Own Message Box We Can Work


With
The first thing to realize is that developing your own message box will constrain you to a certain extent as to what you
can provide with it as the default WPF message box comes with a number of configurable options that you can select
to produce certain results. The only problem is that you cannot change how the default message box is displayed since
it is reliant on the Win API.
Essentially, a message box will request a user to do one of two things, read the provided information and move on, or
ask a questions, which is in practically all cases a yes or no question.
Luckily, with the WPF modal dialogue, which is the type of window we will use for our message box, we can easily
return a true or false value allowing us to handle the second scenario noted previously.

The XAML Markup


The Window
Every display with WPF is made up of XAML markup and the same will be true for our own message box.
To begin with, we will add a new WPF window to our Visual Studio project with the following properties being
defined
Hide Copy Code

Background="WhiteSmoke"
WindowStartupLocation="CenterOwner"
ResizeMode="NoResize"
FontFamily="Arial"
BorderThickness="1"
BorderBrush="LightGray"
AllowsTransparency="True"
WindowStyle="None"
SizeToContent="Height"
Height="Auto"
Width="600"
It should be noted that I made the Background color, WhiteSmoke, which is a nice, calming white instead of the
bright default white color.
Since we will want our message box to be displayed in the center of an applications master window, we set the
property, WindowStartupLocation, to CenterOwner.
We dont want to allow the user to resize our message box, so we will set this property, ResizeMode, to No Resize.
The FontFamily property can be set to any font you prefer.
Like the window, which was described in my previous article, we will make the BorderThickness property equal to
1, keeping it to a nice, thin outline. If you prefer, you can make the borders thicker by incrementing the size. In the
same vein, to make the border unobtrusive, make the BorderBrush color LightGray.
The AllowsTransparency property must be set to True since we will be turning off the chrome with the next
property, WindowStyle, which must then be set to None.
The SizeToContent property is set to Height so that the message window will resize automatically based on
the content it is provided. This also follows that the Height property will be set to Auto.

Finally, we want to provide a standard width for our message window. In this case, we will make the Width property,
600, though, you can make the width any size you prefer.

The Window Body The Dock Panel


The content of our message box (window) is as expected, rather light-weight as it has to be able to display relatively
limited information. The result is that we have to only put a few XAML controls within the default grid that is generated
with each new WPF window and page.
To begin then, we will first place a dock-panel inside our default grid so that we can anchor the subsequent content to
the top of the window as shown below
Hide Copy Code

<DockPanel Name="dpTitleBar" VerticalAlignment="Top">


</DockPanel>
You do not have to apply a name for the dock-panel if you do not want to.

The Window Body The Upper TextBlock


Next, we add in a bar for the window so that we can provide a title-bar for our message box. This is accomplished by
adding a text-block within the dock-panel
You do not have to apply a name for the dock-panel if you do not want to.

The Window Body The Upper TextBlock


Next, we add in a bar for the window so that we can provide a title-bar for our message box. This is accomplished by
adding a text-block within the dock-panel
Hide Copy Code

<TextBlock DockPanel.Dock="Top" HorizontalAlignment="Stretch"


VerticalAlignment="Top" Background="DarkSlateBlue" Foreground="WhiteSmoke"
FontFamily="Arial" FontWeight="DemiBold"
Height="24" Padding="5">Application Message</TextBlock>
Notice that we anchor the text-block to the dock-panel by using the object.property correlation to the dockpanel, DockPanel.Dock, setting it to Top.
Since we want our text-block to span the width of our message box (window) we set the property,
HorizonalAlignment, to Stretch.
To style this part of the display, we opt for a Background of DarkSlateBlue with a Foreground of
WhiteSmoke.
Our FontFamily can be any type of your own choosing as with the colors. I like Ariel, so that is what this
property is set to.
To keep the title-bar slim, we will set the Height to 24 pixels, while centering the title itself with a Padding of
5.

The Window Body The Stack Panel


After the text-block, which will act as our message boxs title\header bar, we will next add a stack-panel that will allow
the message box to accommodate any message length required.
Hide Copy Code

<StackPanel Name="stkpnlMessageBody" DockPanel.Dock="Bottom"


Background="WhiteSmoke" Height="Auto">
Notice that we set the object\property, DockPanel.Dock to Bottom so that whatever is included within the
stack-panel will be anchored to the bottom of the message boxs window.

The Window Body Two New Grids


Within our stack-panel, we will now include two new grids. The first one will allow us to place a left-most image along
with a text-block that will be left-aligned but stretched to the length of the remaining grids second right-most
element.
Notice in the grid markup below how we define two columns; the left one being set to Auto so that it will only take
up as much space as required by the content while the right-hand column is allowed the remainder of all space
remaining. Thus, in the left-hand column, we will place a 6464 pixel image while in the right-hand one, we will place
our message text.
Hide Copy Code

<Grid Background="WhiteSmoke" Height="Auto">


<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Name="imgMessageImage" Grid.Column="0" HorizontalAlignment="Left"
VerticalAlignment="Top"
Source="/SQLServer.SourceControl;component/Images/Exit_128x128.png"
Height="64" Width="64" Margin="30,30,0,0"/>
<TextBlock Name="txtbMessage" Text="" Grid.Column="1" HorizontalAlignment="Left"
VerticalAlignment="Stretch" Background="WhiteSmoke" Foreground="DarkSlateBlue"
FontFamily="Arial" FontWeight="Normal" Height="Auto" Padding="5" Margin="0,30,25,0"
TextWrapping="Wrap">
</TextBlock>
</Grid>
Those of you who are familiar with WPF may ask why the Margin property is still being used in a grid that has
defined columns when such a layout would afford automatic alignments. This may be true but the Margin
properties being used are here to set the content more aesthetically within each column.
Such placement cannot be done with grid column\row definitions alone, though much can be done with them as is.
However, if you still want to design your forms with more precise appearances, the use of the Margin property will
still have to be considered.
Nonetheless, if you are fine with the default placements that grid column\row definitions provide, then there is no
need to use the Margin property at all. I use it also out of habit from my training whereby in earlier years of
development, positional placement of display controls was quite normal and expected.
The second grid allows us to place the Yes\No buttons in a neat manner at the bottom of the message box and to
the left
Hide Copy Code

<Grid Background="WhiteSmoke" VerticalAlignment="Bottom"


Margin="5,5,5,5" Height="Auto">
<Button Name="btnYes"
Content="Yes" HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Background="DarkSlateBlue" Foreground="WhiteSmoke"
FontFamily="Arial" FontWeight="Normal"
Height="24" Width="75"/>
<Button Name="btnNo" Content="No"

HorizontalAlignment="Left"
VerticalAlignment="Bottom" Margin="80,0,0,0"
Background="DarkSlateBlue"
Foreground="WhiteSmoke" FontFamily="Arial"
FontWeight="Normal" Height="24" Width="75"/>
</Grid>
The resultant message box display from the previous markup is shown below

Notice how the command buttons are somewhat lower than what would be expected from the markup shown
previously? You will see why in the next section.

The Source Code in the Parent Window CodeBehind


Module
Similar to ASP.NET WebForms, WPF uses a similar construct to perform what ASP.NET uses to perform server-side
processing but now on the desktop. With WebForms, the backend source code is implemented in what is called a
CodeBehind module. Similarly, WPF uses the same construct to process requests from the XAML display.
In this case, we will show the source code that launches our message box as a result of an action by the user of an
application that requires a yes/no response. Where this response is requested is in what we call the parent window
since the message box will be displayed as a modal form.
And it is here we can add some finishing touches to the subsequent message box display. The code for this is quite
straight-forward as shown below
Hide Copy Code

Private Function Display_MessageYesNoWindow_MessageLogClear()


Dim lboolResult

As Boolean = False

Dim loMessageYesNoWindow

As New MessageYesNoWindow()

Dim loStringBuilder

As New StringBuilder()

Dim loStateProperties
As New
SQLServer.SourceControl.Library.StateManagement.StateProperties()
loMessageYesNoWindow.IMAGE_SOURCE = "MessageWindowWait_128x128.png"
loStringBuilder.Append("You have selected to delete all of the application message log
data. Do you want to continue?")
loStringBuilder.Append(Environment.NewLine + Environment.NewLine)
loStringBuilder.Append(Environment.NewLine + Environment.NewLine)
loStringBuilder.Append(Environment.NewLine + Environment.NewLine)

loMessageYesNoWindow.MESSAGE = loStringBuilder.ToString()
loMessageYesNoWindow.Owner = DirectCast(loStateProperties.MAIN_WINDOW,MainWindow)
Return(loMessageYesNoWindow.ShowDialog())
End Function
In the code above, we have two public properties that are part of the message box CodeBehind module; an
image source property (IMAGE_SOURCE) and a message property (MESSAGE).
If you note the code for the IMAGE_SOURCE property, you will see that we only provide the name of an image and
its extension. This is because within this property, we have also provided the default sub-directory path to the images
in our application in WPF format
Hide Copy Code

Private ssImageSource

As String = "/SQLServer.SourceControl;component/Images/"

Public Property IMAGE_SOURCE() As String


Get
Return (ssImageSource)
End Get
Set(ByVal Value As String)
ssImageSource = ssImageSource + Value
End Set
End Property
The MESSAGE property is merely a string that will contain a message as long as you require. However, note the
code where the Envirionment.NewLine property is successively added to the message. It is the use of this
property that allows us to move the message boxs command buttons down from the image and message being
displayed. This is what provides a nicer symmetry to the display. If this property was not added to the message, then
the command buttons would align themselves right under the message box image. This is fine if this is what is desired
and can also be spaced a little nicer with the addition of some extra padding. However, I chose to use the
Envirionment.NewLine property so I would have slightly more control over this situation.

Returning a Boolean From the Message Box


The last major aspect of this code is the return of a Boolean when the user closes the message box by selecting one of
the command buttons. This is a very simple process since modal WPF windows have the same attributes as a
dialogue window and allow for the return of a true\false value. In the code above, you will see that we return the
display of our message box window as a Boolean result
Hide Copy Code

Return(loMessageYesNoWindow.ShowDialog())
Within the message box CodeBehind module, returning the Boolean value is accomplished via the command
button event fired by setting the DialogResult to True or False
Hide Copy Code

Me.DialogResult = True

Conclusion
Despite the length of this article, the message box modules are quite slim in terms of markup and code. You should
then find it rather easy to modify it to your own preferences and implement in your applications.

In addition, changing or adding the capability of a simple OK result to the code is just as easy since you do not have
to return a Boolean result in this case.
To make things easier in this respect, the complete WPF source code for this message box can be downloaded from
the following link
https://1drv.ms/u/s!AnW5gyh0E3V-g2IBWfD5TCyqHZuj
If you have any questions or comments about this paper, you may contact me at the following
support@blackfalconsoftware.com

License
This article, along with any associated source code and files,
is licensed under The Code Project Open License (CPOL)

Share
EMAIL

TWITTER

About the Author


Steve Naidamast

Software Developer (Senior) Black Falcon Software, Inc.


United States
No Biography provided

You may also be interested in...


Pro

How 5 Companies
Maintain Optimal .NET
Performance

Pro

When Logging Isn't


Enough: A Modern
Approach to Monitoring
Performance in Production

Custom Message Box in


WPF XAML

SAPrefs - Netscape-like
Preferences Dialog

A Custom Message Box

Generate and add


keyword variations using
AdWords API

Comments and Discussions


You must Sign In to use this message board.
Search Comments
Spacing Tight

Go

Layout Normal

Per page 50

Update

-- There are no messages in this forum -Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.161101.1 | Last Updated 7 Oct 2016

Select Language
Layout: fixed | fluid

Article Copyright 2016 by Steve Naidamast


Everything else Copyright CodeProject, 1999-2016

You might also like