There are two modules: (A) MessageBoxModule and (B) PopupBoxModule.
The MessageBoxModule makes use of a standard MessageBox for one feature and a standard Windows Form dialog for another feature. When you run the unit tests you’ll be interrupted by MessageBox and DialogBox popups.
The PopupBoxModule makes use of my custom PopupBox class (which mimics a MessageBox) and a custom DialogBox class for CAB. When you run the unit tests for this module no popup windows will appear, yet the tests will pass and the data will be correct.
The MessageBox can be a handy little device in a Windows Forms application. It’s cousin, the Dialog box, can be even more handy. There are a lot of occassions when you need to prompt the user for a yes/no type of answer, or notify them of some important event, or get some trivial piece of data from them before proceeding.
Unfortunately, the MessageBox and Dialog box are nightmares when it comes to unit testing. You don’t want to trigger a MessageBox popup when you’re trying to run automated unit tests against your Presenters, or you end up with this situation:

This problem only becomes compounded when you consider that in the Component UI Application Block you typically use a WindowWorkspace to show Dialogs. This is a much different way for showing popup windows than the typical Windows Form methodology which involves creating a Form control and calling ShowDialog() on it. The WindowWorkspace doesn’t return a DialogResult, for one thing. For another, you’re using a UserControl instead of a full-fledged Form control.
So how can we get the functionality that we’re used to using with classic Windows Forms technology and still utilize the CAB framework, all the while appeasing our desire to utilize Dependency Injection so that we can easily mock objects and input for use in automated testing?
I’ll show you my solution.
Injecting A DialogBox
The first thing to understand is what we’re trying to accomplish: We want to be able to inject a MessageBox into a Presenter or other WorkItem. The reason we want to inject the MessageBox is twofold: (1) so we can control the input and output of the MessageBox object in a unit testing scenario and (2) so we can prevent it from being displayed when the calling code executes. Preventing the MessageBox/DialogBox from appearing when it is called is the key to making things work in a unit testing environment like NUnit.
There’s one other glaring problem when attempting to emulate a MessageBox/DialogBox in CAB: There is no DialogResult when you use a WindowWorkspace.
Making the MessageBox or DialogBox close is easy enough if you’re using the Smart Client Software Factory; you can just call Presenter.OnViewClose() and the framework will handle the rest. The WindowWorkspace will close itself and the SmartPart. But that actually causes the Workspace to attempt to Dispose() of the SmartPart, which is not what you want in a Dialog scenario. What you really want to accomplish is a two-step process: First verify that the user has selected a specific button (OK/Cancel or the like) which is typically done with the DialogResult, and then fetch output off the Dialog object. To do that you need a Dialog that hangs around after the WindowWorkspace has closed itself. This means hiding the MessageBox or DialogBox instead of having the Workspace close it.
But how do we have a Dialog tell the Workspace to hide it? That’s where our DialogBox base class comes in.
The DialogBox Base Class
The first part of the solution is the DialogBox base class. It is an abstract class derived from a UserControl and implements an ISmartPartInfoProvider interface. This base class is responsible for the difficult part of this solution: handling button clicking and setting a DialogResult.
Normally, when you create a Dialog object in .NET you use as a Windows Form, create your buttons and set the DialogResult property on those buttons. Then, when a user clicks on one of those buttons the DialogResult for the Form gets set.
Our base class, DialogBox, does the same thing when you make a call to the InitializeClickHandlers(). It loops through the Controls of the subclass and looks for Button objects. When it finds one, it wires up an EventHandler to that Button’s Click() event. This is what the DialogBox base class will use to help send a message to the WindowWorkspace that a Dialog button has been clicked and the WindowWorkspace needs to Hide() the Dialog UserControl.
The WindowWorkspace
The next step is to augment the WindowWorkspace. The Smart Client Software Factory provides a subclassed version of the standard WindowWorkspace which has a couple enhancements to it. We’re going to add some code to the Show() method and include one additional method:
code in Show():
if (smartPart is DialogBox)
{
DialogBox box = (DialogBox)smartPart;
box.OnDialogButtonClick
+= new DialogBox.DialogClose(DialogClose);
box.InitDialog();
}
add this method:
private void DialogClose(Control c)
{
OnHide(c);
}
The Subclassed DialogBox
Once we’ve altered the WindowWorkspace and built our base DialogBox class, it’s time to actually use it. We start by creating a new UserControl and having it subclass from DialogBox instead of UserControl. Add buttons and controls, making sure each button has a DialogResult property set.

In the code for the dialog we have to make a couple alterations:
[SmartPart]
public partial class StringFetchDialog : DialogBox
{
public StringFetchDialog()
{
InitializeComponent();
InitializeClickHandlers(this);
}
public string String
{
get { return _stringTextBox.Text; }
set { _stringTextBox.Text = value; }
}
public override void InitDialog()
{
base.InitDialog();
_stringTextBox.Text = string.Empty;
}
}
Notice the bolded lines of text. InitializeClickHandlers is a base class method that is used to wire-up the Click event for any button on your Dialog. This saves you from having to perform the DialogResult logic on every Dialog you make. The other thing we’ve done is override the DialogBox’s InitDialog() method. This method gets called by our altered WindowWorkspace when it shows a Dialog. You should perform any initializating on your Dialog in this method. In this case we’re setting the TextBox value to String.Empty so that each subsequent time the dialog is shown you do not have the previous text still in the field.
Now our dialog is ready to use.
Presenter Injection
Typically you’ll have some Presenter object or WorkItem that needs to interact with the user in some modal way. Your DialogBox is a dependency that your Presenter is relying on, so you need to provide your Presenter with a DialogBox either through constructor-based injection or property-based injection. Here is a snapshot of the Presenter code:
private IStringService _service;
private PopupBox _popupBox;
private StringFetchDialog _dialog;
[InjectionConstructor]
public PopupBoxViewPresenter(
[ServiceDependency] IStringService service,
[Dependency(Name = SmartPartNames.PopupBox)] PopupBox popupBox,
[Dependency(Name = SmartPartNames.StringFetchDialog)]
StringFetchDialog dialog)
{
_service = service;
_popupBox = popupBox;
_dialog = dialog;
}
Take note of the use of the [Dependency] attribute here with a strong name on the StringFetchDialog. By default, ObjectBuilder will look for a StringFetchDialog with the same name in the hierarchy of WorkItems. If it cannot find one it will create a new one, much as if you had specified:
[Dependency(NotPresentBehavior = NotPresentBehavior.CreateNew)].
This behavior works to our advantage.
In our unit testing class we will build a new StringFetchDialog and add it to our TestableRootWorkItem prior to adding the Presenter under test. This will cause the Presenter to get a reference to our prebuilt StringFetchDialog which we can manipulate for testing purposes. However, in the real WorkItem we will not create a StringFetchDialog. Instead, we’ll let the ObjectBuilder do it for us when it can’t find it.
The Unit Test SetUp
[SetUp]
public void SetUp()
{
_workItem = new TestableRootWorkItem();
_dialog = _workItem.SmartParts.AddNew
(SmartPartNames.StringFetchDialog);
This is the beginning of our SetUp method in our TestFixture. Notice how we’re adding a new StringFetchDialog and maintaining a reference to it locally in the TestFixture. This allows us to do the following in a test:
[Test]
public void AddString_UserSelectsOK_AddsStringToView()
{
_dialog.String = "Enchant";
_dialog.DialogResult = DialogResult.OK;
_presenter.AddString();
Assert.AreEqual(1, _view.AddNameValues.Count);
Assert.AreEqual("Enchant", _view.AddNameValues[0]);
}
Here we set the expected DialogResult and data properties. Our presenter has been injected with this dialog so whatever values we set it will make use of. This allows us to control the state of the DialogBox for testing. The question you may be asking now is, “How do you prevent it from being shown during a unit test?”
Preventing Dialog Display During Unit Testing
There’s two parts to this solution. The first part is to create a MockWorkspace that does nothing when Show() is called. We can do this by implementing the IWorkspace interface.
class MockWorkspace : IWorkspace
{
public void Show(object smartPart)
{
}
public void Show(object smartPart, ISmartPartInfo smartPartInfo)
{
}
}
The second part is to use this Workspace instead of a real Workspace in our TestableRootWorkItem:
[SetUp]
public void SetUp()
{
_workItem = new TestableRootWorkItem();
_workItem.Workspaces.AddNew
(WorkspaceNames.PopupBoxWorkspace);
_workItem.Workspaces.AddNew
(WorkspaceNames.DialogBoxWorkspace);
Now when we run our unit tests the StringFetchDialog will not popup on the screen. This is the behavior we’re after.
Using The Dialog In A Presenter
So we have a DialogBox that works with CAB and doesn’t popup when we unit test. How do we actually call this code?
First, I’ll show you the Windows Forms way, which we’re all pretty familiar with:
StringFetchDialog dialog = new StringFetchDialog();
if(dialog.ShowDialog() == DialogResult.OK)
{
_service.AddString(dialog.String);
}
The new way isn’t much different:
WorkItem.Workspaces[WorkspaceNames.DialogBoxWorkspace].Show(_dialog);
if (_dialog.DialogResult == DialogResult.OK)
{
_service.AddString(_dialog.String);
}
The main difference is that we don’t have to new-up a Dialog each time we want to use it. Instead, our Presenter has been injected with a StringFetchDialog already, and we juse reuse it each time we need to query the user. Instead of making a call to ShowDialog() we ask the Workspace to show it.
The PopupBox
The other thing I’ve written is the PopupBox class, which is a special implementation of the DialogBox base class designed to mimic the behavior and usage of the standard MessageBox class. The main difference between it and a MessageBox is that the PopupBox is not static. Like the StringFetchDialog it is an instantiated class that is injected into the Presenter. Since it’s a fairly common control it may be best to add it at the Shell level, so all WorkItems have access to it.
MessageBox Way
In the sample project I use a MessageBox to query the user to determine if they really want to change the background color of the form. The calling code looks like so:
DialogResult result =
MessageBox.Show(
"Do you want to change the background color of this form?",
"MessageBox",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (result == DialogResult.Yes)
View.UpdateBackgroundColor(true);
else
View.UpdateBackgroundColor(false);
The CAB-friendly version looks very simliar:
_popupBox.Initialize(
"Do you want to change the background color of this form?",
"Change Background Color",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
WorkItem.Workspaces[WorkspaceNames.PopupBoxWorkspace]
.Show(_popupBox);
if (_popupBox.DialogResult == DialogResult.Yes)
View.UpdateBackgroundColor(true);
else
View.UpdateBackgroundColor(false);
Instead of making a call to MessageBox.Show() you make a call to PopupBox.Initialize(), passing in the parameters you want to format the box correctly.
These two classes are contained in the Infrastructure.Library project of the CabSample application attached to this post. To use these objects in your own project you can just copy and paste them. You’ll also need to adjust the WindowWorkspace accordingly, or copy the class from my file.
With these two objects in hand, the PopupBox and DialogBox, you can get around one of the major hurdles in unit testing CAB applications. Prior to having these objects I would have to skip any subroutine that used a MessageBox or DialogBox. That’s disappointing, because I like to have 100% code coverage in the classes I’m testing. I especially like to be able to simulate user input for Dialog situations. Now I can do that.
Enjoy.
Steve K says:
Hi Chris, thanks for sharing this great tool! I wanted to let you know that I can’t see the images in the post, it looks like a small gray box where an image should be.
February 27, 2007, 9:56 pmanetdeveloper says:
I don’t know whether this is the right place for this problem but I am stuck into it. Please don’t mind and if possible provide me the solution. I have also created a discussion on codeplex.
I have installed GAT and SCSF and working on the HandsOnArchitect project. I finished the first one the left the 2nd in between. Then I tried to create the smart client application from the original guidance package but it gives the following exception.
Project Template wizard
The problem was encountered creating the subproject ‘Infrastructure.Library’. The filename, directory name, or volume label syntax is incorrect.
(Exception from HRESULT: 0×8007007B)
Please help me on the same as I am getting the same problem even after reinstalling SCSF.
May 8, 2007, 7:00 amAlexandre Roba says:
Tanks for sharing with use the package. I have look at it closely, but the comments of the post and the code are no more in line… Especially on the closing part. The InitializeClickHandlers() has desapear. I’m wondering now how do you handle the closing after a DialogResult Update? Where do you plug the raising of WindowWorkspace_SmartPartClosing?
thanks for your help.
May 24, 2007, 1:27 amDavid Elliott says:
I was wondering if you can have the popup be modal/non-modal on a per module basis?
As a really rough example, if I have a form that I am entering data into and an auto save failed which creates a messagebox to pop up, I don’t want to be REQUIRED to click ok. I want to be able to continue entering data into my form.
June 26, 2007, 10:26 amDavid Elliott says:
I was wondering if you can have the popup be modal/non-modal on a per module basis?
As a really rough example, if I have a form that I am entering data into and an auto save failed which creates a messagebox to pop up, I don’t want to be REQUIRED to click ok. I want to be able to continue entering data into my form.
June 26, 2007, 10:26 amChris says:
David,
There’s an easier way to do this actually. I should probably take this post down, or modify it. Intead of using special workspaces for MessageBox type behavior, it’s best to just provide a method on the View that the presenter can call to facilitate showing a MessageBox. You end up with code that looks something like this:
View.ShowMessageBox(”MyTitle”,”Message….”, etc….)
If you are really crafty you can wrap all of that up into a base view class (with associated interface of course) that all of your views inherit from. You can then provide as many overloads as you like for various messagebox behaviors (like specifying button configurations, etc.).
In this way you can avoid real messageboxes from popping up during unit testing, but you can still provide for the real thing in your application. Hope that’s clear. If not, email me.
June 26, 2007, 10:37 amDavid Elliott says:
So my original question deviates a little from the original topic. It’s not so much a NUnit question but a question in general. I am looking for a way to have a message box pop up during normal user interaction, such that it doesn’t hang the UI thread until the user clicks the message box. The user would be allowed to continue doing what they were working on or could go to the menu bar, etc. Basically the message box would have to be aware of where use is and determine if it needs to be modal or non-modal.
June 27, 2007, 9:04 amChris says:
MessageBoxes, by their design, are modal. That is their function.
To have a non-modal MessageBox you would have to write your own dialog class.
In terms of CAB, nothing changes either way. The best pattern to use is still the same: have the presenter make a request to the view and allow the view to handle the implementation details. It could then either show a MessageBox, Dialog, or custom class if your choosing.
I would personally beware of non-modal “messagebox” type of classes however. A MessageBox is meant to interrupt the user; it demands user attention. It is not meant to be ignored. A non-modal MessageBox would be like internet porn spam; you could potentially have dozens of messageboxes opening on the user simultaneously flooding them with little windows. If you need to notify the user of something but you don’t consider the notification important enough to use a MessageBox in a modal manner (not wanting to interrupt the user) then consider utilizing some other notification method, like the status strip or a textbox on the toolbar.
Think long and hard about the situation you’re dealing with and the proper way to design a solution.
June 27, 2007, 9:54 amSteve K. says:
Hi Chris,
I’m taking a second swing at this as I have a situation where I need to get a DialogResult back from my Modal Views.
I read your post and jumped into the sample, right away I realized that these really are intended (as you said) to only be simple dialogs. In my situation I need to show some very complex Views complete with MVP – looking at your sample I’m not seeing how I could do this.
For example, if you wanted to use MVP on your login view, how would you go about that?
I’m sure it’s obvious, but I’m not seeing it.
Thanks for this great post, it must have taken you quite awhile to put this together, I appreciate it.
-Steve
July 18, 2007, 9:19 pmanetdeveloper says:
Hi Chris,
I am a newbie to CAB and am using CAB first time in my project. I am not using SCSF so I am not sure how should I use this in my project but I desperately seeking such functionality.
Please help me out.
- Amit
September 13, 2007, 12:05 pmanetdeveloper says:
Hi Chris,
Thanks for the immediate response! I really appreciate that.
I am not using SCSF so I must say it is the same approach for the MVC pattern in CAB without SCSF.
But here is my detailed problem..
I have a document-centric application in which the user can say new document or open document from the UI extension site. I handle that command in the main workitem, deserialize in my business logic and check whether it is password protected. If it is, then I will show a dialog to take the password. As I understand, if I use WindowWorkspace, it doesn’t return DialogResult so then how to handle that…do I design a normal for as a dialog or it is a breach of CAB architecture? Normally in CAB all views are user controls[SmartParts].
Secondly, in regard to Message boxes, as the user says new document, I just check if the other document is already open, and if it is, I just want to prompt user to close current and open new. In this case, I want to show the message box. Now this is also handled in my workitem not in controller.
The thing is I am using CAB for hte first time as we have multiple such application and later if we want to integrate these, the effort would be less due to the modular architecture of CAB.
I would definitely appreciate your help.
Regards,
September 22, 2007, 1:45 amAmit