Thursday, July 23, 2009

Walkthrough: Custom Controls development for .Net Compact Framework (Episode 1)

Overview: What is this guy talking about?

In most of the projects I had, there was always the need of develop at least one custom control to provide a really good user experience. As I said before in several posts, the user experience is such a critical aspect of any mobile development, that the standard controls are never enough for fulfilling it. And this need is even beyond the lack of some desired features in the current version of Windows Mobile standard controls. Even if we would have cinematic touch scrolling or transparent backgrounds in .Net CF controls, we will highly probably still needing to develop custom controls providing the right user experience to our users, when showing specific business data or interactions that cannot been achieve with the standard controls.

Unfortunately, there is not enough guidance about how to develop a .Net CF custom control in an start-to-end tutorialish approach, a way that you can follow it from scratch, passing thru a sequence of steps that will lead you to a finished custom control, with a clear understanding of what you should take care about during the development process.

So, I decided to start a series of posts on how to develop a real-world custom control for .Net CF. My hope is that these posts will be useful for any developer who needs to develop a .Net CF custom control for a real-world application. That includes people working with me and even myself :). My goal is to be focused not only on the User Control UI elements coding, but also on its usability during the development and application support, and how this control should interact with the business elements, taking care of keeping them decoupled and testable while the control stills providing the desired UX and performance.

Does it sound good? Quite ambitious maybe? I guess YES, YES. And I’ve already spent too many typing on this overview, so let’s start.

What is a Custom Control? (Custom controls Vs. UserControls)

For who are new to controls development in .Net, there used to be a big confusion between what is a UserControl and what is a custom Control.

A UserControl is basically a UI component, which is made of other controls which can also be User Controls, and that has a design-time experience very similar to the Form’s one. A UserControl is built based on composition. Its goal is helping you to reuse a set of UI elements on more than one Form providing a consistent look & feel and usability from both the development and user experience point of view.

So, if you need to show a Customer Details section in several views, you can create a CustomerDetails user control which will include a set of labels which will be filled with the customer info in the same consistent way along your forms. For achieving that you can just create a new User Control from the “Add Item” menu, call it “CustomerDetails.cs” and in a friendly designer experience, you can drop some labels, change its properties like name, text, font, position them as you prefer, and then using the UserControl code behind, expose a Customer property and fill your labels based on it.

In contrast, a custom Control is a single control. A .Net control which is developed “from scratch” and just by coding. To make it simpler, it’s basically a class that inherits from System.Windows.Forms.Control and overrides some of the Control’s methods, like OnPaint, to provide the expected user experience.

While a UserControl is easier to develop and support, a Custom Control is lighter and faster at runtime, and it gives you the highest flexibility you can get in a .Net control, because you are free to draw whatever you want, even animations, and to handle input messages like keyboard and touch events.

Why do we need a Custom Control? (Understanding the business)

During this walkthrough, I will use an imaginary but concrete business case, because I think it’s the best way to understand the three main questions about a Custom Control:

1. Why do we need it?
2. What do we need from it?
3. How can we do it?

So, to answer the first question let’s start understanding the business case. My case study is an imaginary company that publish a worldwide Restaurant Guide, let’s call it RestoGuide. It has around 150 reviewers around the world, which should collect information about restaurants and send the results to its centralized database. To improve the process, RestoGuide has decided to implement a mobile application (RestoGuideMobile)that will be used by the reviewers to enter the information on site, with the ability to send it almost at real time updating the database for potential online queries.

By using RestoGuideMobile, the reviewer avoids taking notes on paper or recording them on tape, with the need of enter them into the RestoGuide web site later, doubling the risk of human errors. RestoGuideMobile can be used while he is in the restaurant, helping him during the process, and allowing the immediate upload to the centralized database.

Well, there is no mystery on this idea, RestoGuideMobile is just another mobile app which can make the life of its user tons easier. But for making this assertion true, we should take it to the letter. Our app should really make the life of its user tons easier. And the users will interact with our app using the forms and controls we have. Then, for achieving our goal, we should take our app UX very seriously and don’t hesitate in spent several design and development cycles on it. It should fit the business perfectly and the best way is to start with some mockups.

An application will have lots of mockups, but we’ll focus our work on one screen:

restaurants

This is a mockup of the third step of the Review wizard, it let’s the user to enter the open days and rating for a given restaurant. The screen has been designed thinking in an easy way to enter the data using a mobile device. It’s easy to read and easy to change. But… is this mockup easy to implement in a Windows Mobile .Net Compact Framework application using standard controls? I think this is the answer for question 1, “Why do we need to use custom controls?” we need them for tackling some specific UX challenges, like some of the controls we can see on this mockup, and we need them because we cannot box our mind on a reduced set of controls when we design a good mobile user experience.

From the mockup, we can see at least the following custom controls:

  • WizardHeader: Could be implemented with a User Control, but it has some inline font changes that could be much easier to implement in a Custom Control, and we can get a better look too.
  • OpenDays: This will include a week days multi-selector, that would be implemented using a ListView or a set of labels in a User Control, but a custom control will be much lighter and it gives us the possibility of making it look really good.
  • RatingStars: A typical control for show/enter a rating, but which is not present in Windows Mobile. Again, it can be implemented with a UserControl with a set of images, but a custom control will give us the chance of doing it lighter and to play freely with it.

During the next posts, we’ll implement the three custom controls, and we’ll be tackling the diverse challenges along the way, like:

  • Designing the control API
  • Drawing the control elements
  • Providing a design time experience
  • Resource management
  • Building Drawing Helpers
  • Avoiding flickering (Double buffering)
  • Handling the user input
  • Animations

Well, we have lots of work to do, so stay tuned, this will have tons of fun!

Friday, May 22, 2009

Mobile Application Blocks new Community Drop (05-21-2009) available for download.

I’ve just uploaded the latest drop of the Microsoft Patterns & Practices Mobile – Mobile Application Blocks to the CodePlex site.

This new Community Drop (05-21-2009) includes the following changes:

  • All the SQL CE references have been updated targeting to SQLCE 3.5 SP1 (3.5.1.0)
  • The ConfigSectionEncrypt sample tool which can be used to encrypt configuration sections has been ported and included on this drop.
  • For each block we've created separate projects for .Net CF 3.5 and 2.0. So you currently will find projects named:
    • <BlockProjectName>.csproj - Targeting .Net CF 3.5
    • <BlockProjectName>.20.csproj - Targeting .Net CF 2.0
  • ContainerModel Block performance improvements and code simplifications.
  • Readme.htm file included with basic information about the project and online resources.

Notice that even the blocks were ported thinking on .Net CF 3.5, they still being compatible with .Net CF 2.0 and in fact, most of the blocks source code on previous drops were targeting 2.0. In this version we’ve cleaned up things and you have specific projects for each version.

The other main change is the inclusion of the ConfigSectionEncrypt tool which was absent on previous drops. It’s a great sample and companion for working with the Configuration Block using Encrypted Sections. It was just a straight port at this time, and probably the tool’s UI is not the most intuitive you have seen. So, I’ll try to clarify how to use it in future posts.

About the installation, I recommend you to remove any previous version of the blocks before installing this, and, if you’re installing the blocks for first time, please double check our Requirements Page.

Thursday, May 14, 2009

VS2008 Add New Project: Smart Device Unit Testing Project? A simple project template that would make things easier

Are you tired of the “Create Unit Test” wizard as the only way to create a Smart Device Unit Testing Project? Don’t you feel comfortable with the alternative of edit a Compact Framework Class Library project file changing Guids to convert it into a Unit Testing project? Well, let me try to help you with this smart device unit testing project template that maybe fits your needs.

You can put this zip file into the “%userprofile%\Documents\Visual Studio 2008\Templates\ProjectTemplates” folder, and it will appear as a new option under “My templates” when you try to create or add a new project into your solution:

image

Much better! At least IMO ;). Enjoy!

Wednesday, April 29, 2009

Q4Tech Mobile Updater Application Block is now part of Mobile Contribute

Q4Tech has moved its open source Mobile Updater Application Block as part of the Mobile Contribute Project at CodePlex, under the MS-PL license.

The block hasn’t been upgraded yet, and it stills targeting VS 2005, .Net CF2.0 and WM 5.0, but it was definitely a good move, and being in a community contribution project we can expect seeing it alive for a long time and hopefully we will see an updated updater soon ;)

Friday, April 24, 2009

Using Balsamiq Mockups to design a Windows Mobile app UX

UPDATE (7/17/2012): Please use this link for downloading the template.

As you probably already know, or are just about to realize, the success of any mobile application mostly depends on the user experience it provides. Besides how functional is a device which can be easily transported with you, the reduced size and autonomy required makes it a resources constrained machine not only in terms of processor, battery life and memory, it’s constrained also in terms of screen size and user interaction capabilities.
In fact, most of the mobile applications should interact with users without a mouse, a full sized hardware keyboard or even without any hardware keyboard at all. What’s worst, the apps should show the information and allow input in a very small screen. If you take in account that the scenario is even more complex because your UI would need to target several form factors and orientations, the UX design is something that you should be focused on and work on very seriously from the beginning of your development.
A great way to get the feeling of a UX before of building it is drawing mockups. You can do it by hand or using some tools around there, like Microsoft Office Visio and some custom stencil add-ins available on the web.
One tool I really like is Balsamiq Mockups. You can build mockups having a relaxed hand-drawn look’n feel which is great for sending a clear UX message without the noise of design specific elements like icons and so on. This way, the customer knows that you’re showing a just a mockup, not screenshots, and at the same time he gets clearly what is the UX you’re proposing.
A sample mockup of a login screen with the keyboard open can look like this:
image
And an Outgoing Orders list screen can look like this:
 image
Really cool stuff, isn’t it? You can understand clearly what are the space constraints in your design and how the user should interact with the UI elements. Building a mockup you’re actually designing the real full User eXperience for your app.
Unfortunately, Balsamiq doesn’t include Windows Mobile mockups templates out of the box. But I did the homework, and included the template I built for default WM Professional Edition into their MockupsToGo templates site.
You can have a look at it and download it following this link: Windows Mobile Professional Edition Mockups.  (The old link doesn't work anymore, please use this for download it.)
I’ll add some extra form factors later so we can build mockups for square screen and Standard Edition also.
I really like this tool, but I should also say that there are a couple of things that I don’t like about Balsamiq:
  • It relies on Adobe Air
  • It doesn’t have any freehand drawing tool.
  • It lacks of some basic UI and annotation elements.
The good news is that it stills growing up, and having custom templates you can use it as a great mocking tool for windows mobile applications.
Hope you find it as useful as I do!

Wednesday, April 22, 2009

How to convert an existing Smart Device project into a Smart Device Unit Testing Project

Since I posted about Smart Device Unit Testing using the integrated Visual Studio 2008 Testing Framework, I got a couple of questions regarding how to convert an existing project to a Smart Device Unit Testing Project. Well, let me try to help with the port on this post.

1. It must be a .Net Compact Framework 3.5 project

First of all, a Smart Device Unit Testing Project is a .Net Compact Framework 3.5 Class Library project. So, you may need to upgrade your project to the latest .Net CF version (In Solution Explorer right click your project and select Upgrade Project).

2. Add Visual Studio Testing Framework References

Right click on References folder and select “Add Reference”. Switch, if you’re not already in, to the Browse tab and enter the path of the UnitTestFramework assembly for smart devices which typically is on

C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.SmartDevice.UnitTestFramework.dll

3. Include the Smart Device Unit Testing TypeGuids

Open the project source code. You’ll need first to unload the project by right clicking on it and selecting "Unload Project”. Next, please right click on it again and select "Edit Project File”.
The .csproj project file is an xml file containing project definitions. Please look for the <ProjectTypeGuids> element, and replace it with the following:

<ProjectTypeGuids>{73A5A715-AF05-47af-9C33-47A864AF9AE7};{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

Save the file and right click on your project again and select “Reload Project”. If Visual Studio asks for your confirmation please select Yes.

4. Add a Test Run Configuration File

Now your Smart Device project has been turned into a Smart Device Unit Testing Project. But you need to define at least one .testrunconfig file targeting the emulator or an actual device to run your tests. If you are not familiar with how to add a test run configuration file, please take a look at this post.

5. Make your tests build and start running them!

It’s time to build your code… and just run the tests on the target platform of your choice!.

Piece of cake! Isn’t it? ;)

Friday, April 17, 2009

What’s new on the Mobile Application Blocks Community Drop (03-31-2009)?

It was two weeks ago, but we have a new community drop on the CodePlex site for the Mobile Application Blocks.

This new community drop includes the return of the Subscription Block as part of the project. It hasn’t been included on the previous drop but it was ported and included now.

The other major change was the integration of great updates from the Microsoft Dynamics Mobile product team. They did several wonderful improvements around the Configuration Block, the Connection Monitor Cell Connection, Subscription Block, Endpoint Catalog and the Disconnected Agent. Those improvements have been integrated in our code base in a TDD approach.

One interesting addition was the IWSCredentialService interface as part of the Disconnected Agent Block. This is a side effect of an new abstraction on the Endpoint Catalog.

The Endpoint Catalog is the responsible to provide information required to access a logical endpoint as the URL address and authentication related data depending on an specified network name. E.g. you may need to consume a web service and for your application this web service can be identified with a logical name such as “ProductsService”. That web service can require different URL addresses and even different credentials for different networks, so if you’re connected to the internet you may need to use:

URL: “http://mycompany.com/services/productsservice/
Username: joe.mycompany.com
Password: xxxxxx

But if you’re connected to the intranet, you can access it directly using the following information:

URL: “http://services/productsservice/
Username: joe
Password: xxxxxx

The Endpoint Catalog used to address this issue by providing a catalog with default configuration and specific configuration by network name for a logical endpoint name. This configuration information used to include the address and credentials (username, password and optionally the domain). This information is retrieved from the configuration file, which can be encrypted to keep your data safe.

That approach was good, but it carries on with two issues:

1. We don’t have a clear entry point to inject a service that can ask the user for credentials if needed.

2. We don’t have a way to reuse credentials for several endpoints or networks.

To address both issues, the Dynamics Mobile group has included a new abstraction of the credentials resolution, defining that the endpoint catalog won’t include the authentication details anymore, but only an account name. So, you can now specify that your endpoint configuration from the internet is:

URL: “http://mycompany.com/services/productsservice/
AccountName: “MyInternetAccount

And we can point several endpoint configurations to reuse the same account by using the same account name.

At the same time, when we need to inject i.e. the actual credentials into the web service proxy, we can use a Credential Service to resolve this account name to actual credentials.

This is what we’ve included as part of the Disconnected Agent. A new IWSCredentialService and a default implementation that retrieves the credentials for each account name from the configuration file named the ConfigurationCredentialService. With this interface, you have now a good customization point where you can inject your own Credential Service which would ask the user for credentials for a given account name when needed.

I’ll talk later about the Connection Monitor design changes, but in the meantime I invite you to download the drop from http://mobile.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=25565 and take a look at the full list of changes on the wiki Changes from MCSF v1.

I suggest you also take a look at this great introductory post of Kzu regarding the new Container Model block.

Have a nice weekend!

Wednesday, February 25, 2009

Patterns & Practices Mobile Application Blocks First Community Drop available

As I posted before, we’re working on the new Community Release of the Patterns & Practices Mobile Application Blocks, formerly Mobile Client Software Factory. And this week we’ve started to publish early bits on the Codeplex site. In fact, this is our first community drop, and there still much work to do, but it’s a good first look at what we’re working on.

We’ll continue publishing community drops so you can follow the project progress and give us some feedback before we ship. Keep in touch!

Tuesday, February 10, 2009

Working on a new Mobile Client Software Factory (VS 2008, .Net CF 3.5, WM 6.x!)

It’s been almost two years since I started working on the Microsoft Patterns & Practices Mobile Client Software Factory, and those application blocks, shipped on July 2006, still being very valuable for the mobile developer. But it’s really hard to install it on Visual Studio 2008, in spite of some nice articles about it, like this great one from Glenn Block, which have some little missing steps I sent to Christoph and he posted here.

Well, soon you’ll be able to install it and without all that pain. It’s time to have a new set of mobile blocks updated and working on VS 2008, Windows Mobile 6.x and .NET CF 3.5. Some of the original MCSF team members (Per, Francis, Rohit, Alex, Kzu and me) with the help of an excellent advisory board, were started working on updating some of the original blocks (Configuration, Data Access, Connection Monitor, Endpoint Catalog, Subscription Manager, Disconnected Agent and Password Authentication) and building some new ones targeting modularity and location awareness. As you can see, the Mobile Composite UI Application Block won’t be updated and it will be removed from the new version, same with OAC which has been already updated by Clarius.

This version will be published on http://mobile.codeplex.com/ and ideally it will be the place for future great mobile development blocks.

We still working on prioritization and full feature set. Your feedback is totally welcome. If you have any suggestion, bug report or comment regarding this new project, please feel free to contact me: jose@mobilepractices.net.

Thanks!

Friday, January 30, 2009

Making your Smart Device Unit Tests run on the desktop

In spite of Smart Device Unit Testing in Visual Studio 2008 is working really good, you may want faster test runs for doing Test-Driven-Development. Actually, that’s what I want :). In that case a very good option is to perform small TDD cycles running the tests on the desktop and run them on the device after some significant progress. But, how can we make our tests run on the desktop?

Adding a Desktop Test Run Configuration

The first step is quiet easy, you just need to add (if you don’t already have one) a new .testRunConfig file. Right click on the solution and Add – New Item – Test Run Configuration file. I like to call it “Desktop.testrunconfig”. The default configuration should work, so closing the properties dialog should be enough.

The second step is even easier, we need to select Desktop.testrunconfig as the active configuration, so, go to the Test menu, Select Active Test Run Configuration and click on Desktop (desktop.testrunconfig).

image

You are now ready for run your tests on the desktop!. Assuming that all your tests pass on the device, hopefully, all of them will also pass on the desktop. But, that was not my case! My project includes 12 tests passing on the emulator, but 5 of them don’t pass on the desktop. What’s going wrong?

Handling Windows Mobile specific functionality

As we’re developing a mobile application, our unit tests may include some windows mobile specific functionality which cannot be run on the desktop. It can be using a Windows Mobile API for trying to access the Outlook Mobile Contacts, checking if a new appointment has been scheduled, sending an SMS message or checking the battery level. We need to identify those scenarios and avoid them when running on the desktop.

In two of my failing tests, the tested code uses an API which doesn’t exist on the desktop. To avoid it from failing on the desktop, I need to place it inside an IF statement asking for the current platform and executing it only if it’s the expected platform. You can use the following code snippet as a way to do it:

[TestMethod]
public void testName()
{
if (Environment.OSVersion.Platform == PlatformID.WinCE)
{
// Test body here
// ....
}
}

ExpectedException fails!


The other 3 failing tests are verifying cases where an Exception is expected. All of them use the ExpectedException attribute for this purpose, and it’s ignored when you run a smart device unit testing project on the desktop.


You have two options here: 1. Avoid the tests when running on the desktop as we did before 2. Replace ExpectedException with an alternative approach. As I want to keep most of the test running on the desktop as possible, I prefer the second one.


Actually ExpectedException already has some disadvantages even besides this smart device / desktop running issue. With ExpectedException we can not check that an specific line of the test is the responsible for throwing the exception, or we cannot validate any additional info of the exception, like the message or an InnerException, we just can check for an exception type. So, this is not only a problem, this is also an improvement opportunity, and I like the XUnit approach for this, with the Assert.Throws method. So, why we cannot just implement something similar as follows:

public static class ExtendedAssert
{
public delegate void ThrowsDelegate();

public static Exception Throws<exceptionType>(ThrowsDelegate target)
where exceptionType : Exception
{
try
{
target();
Assert.Fail("No Exception was thrown.");
}
catch(exceptionType ex)
{
return ex;
}

return null;
}
}

Now we can replace a test like this:

[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void BackgroundSizeSmallerThanSizeThrowsArgumentOutOfRangeException()
{
Desktop desktop = new Desktop();
desktop.Size = new Size(20, 20);
desktop.BackgroundSize = new Size(5, 5);
}

With something like this:

[TestMethod]
public void BackgroundSizeSmallerThanSizeThrowsArgumentOutOfRangeException()
{
Desktop desktop = new Desktop();
desktop.Size = new Size(20, 20);
ExtendedAssert.Throws<ArgumentOutOfRangeException>(
delegate { desktop.BackgroundSize = new Size(5, 5); });
}

Now, the test pass on the device and also on the desktop, and at the same time, it’s clear what line should throw the exception. Enjoy!