Take the 2-minute tour ×

We work extensively in the .Net Compact Framework and Windows Mobile. I've seen plenty of questions come up regarding specifics to development of ASP.Net apps or other .Net based desktop apps but nothing CF specific.

Anyone else a mobile developer out there that can share some things to start doing, stop doing, and avoid doing when developing in the Compact Framework?

share|improve this question

closed as not constructive by casperOne Dec 20 '11 at 18:01


Closed as not constructive, yet it has 56 uptics and 93 stars; this reminds me of the clueless cat who told Elvis to go back to driving a truck. –  B. Clay Shannon Dec 11 '13 at 17:06
@B.ClayShannon: note the date of this question. Stack Overflow standards have changed in five years. –  John Saunders Dec 11 '13 at 17:26
Meaning what - it was a good question for three years, and then it was determined it was not even constructive? Based on the popularity and quality of the accepted answer, I find that hard to fathom. The question elicited a very worthwhile response (upvoted over a hundred times!) and thus the question was and is demonstrably constructive. –  B. Clay Shannon Dec 11 '13 at 17:31
@B.ClayShannon: meaning that it used to be considered a good question, back when Stack Overflow was very young. But we learned from our mistakes, and don't mind correcting them. –  John Saunders Jan 2 at 2:08
Well, if it's your site, you can do what you want, but enough nonsensical moves like this and people will gravitate away. –  B. Clay Shannon Jan 2 at 16:11
add comment

14 Answers

up vote 112 down vote accepted


  • Use a physical device whenever possible (not the emulator)
  • Test with multiple devices (different vendors, different models)
  • Concentrate testing around sleep/wakeup behaviors
  • When using MSTEST unit tests, never use private accessors
  • Avoid ActiveSync like the plague - debug using CoreCon direct
  • Get familiar with RPM and start using it early
  • Reuse objects when possible
  • Avoid doing a lot of work in a Form's ctor - off load it for lazy load or in a background thread
  • Load Forms on demand when possible (not all of them at once)
  • Cache the frequently used Forms, create infrequent ones on demand
  • Keep image resolutions low
  • If a class exposes Dispose use it. Always.
  • No app is too small to benefit from MVC/MVP patterns
  • Don't use the Microsoft CAB/SCSF port for the CF (the people who ported it obviously never actually used a resource-limited device)
  • Get familiar with the concept of "occasionally connected" if you will be doing any remote data/service activity
  • Docking and Anchoring are your friend and your enemy - test run-time screen rotations and multiple resolutions (even if you think you won't target them, because you're probably wrong in that thinking)
  • Look at, but don't heavily invest in the device deployment package project type. It has major limitations that will likely bite you. A batch file works surprisingly well or a custom MSBUILD task to call CabWiz
  • Brush up on your C++ and P/Invoke skills. You will need them. It's almost impossible to write a useful CF app without P/Invoking something.
  • Code to the lowest common denominator for targets.
  • Partial classes are your friend, especially for dividing logic between target types (PPC, Phone, non-mobile CE).
  • Avoid running an app from persistent storage, especially for CE and pre-WInMo 5. Copy to RAM and run from there to prevent demand-paging from killing you, especially after a sleep/wake cycle.
  • Apps should not care about sleep/wake transitions, but that's pure theory. Sleep wake *will change your app behavior, so again test, test, test.
  • Did I mention test? Especially on every device you can get your hands on? Buy cheap hardware off of eBay for your test lab. Having more devices is more important than having the latest unless you intend to use a specific feature of a newer device.
  • Ask for divine intervention if you plan to use bluetooth programmatically. Get familiar with the Widcomm and Microsoft stacks and understand that they aren't the same.
  • Watch the MSDN webcast on memory management in the Compact Framework. Watch it again for the stuff you missed the first time.
  • Watch out for sleep/wake invalidating internal handles and causing access violations. This is more esoteric but certainly happens. For example, if you're running an application off of a storage card, the entire app isn't loaded into RAM. Pieces in use are demand-paged in for execution. This is all well and good. Now if you power the device off, the drivers all shut down. When you power back up, many devices simply re-mount the storage devices. When your app needs to demand-page in more program, it's no longer where it was and it dies. Similar behavior can happen with databases on mounted stores. If you have an open handle to the database, after a sleep/wake cycle the connection handle may no longer be valid.
  • Install the evaluation version of Platform Builder. The source code for a whole lot of things is in there (like the network UI, many drivers, etc) and when your P/Invoke code isn't doing what you expect you'll at least have a place to go look for the "why".

added 5/25/10

added 7/27/10

  • If you're after a aesthetic UI, be prepared to do a lot of custom or manual drawing.
  • If you're doing custom or manual drawing and you need to use transparency, get ready for a load of frustrations and having to write wacky code or call native code directly to work around shortcomings in the CF.

added 11/22/11

  • Don't assume that just because a namespace or class exists in the BCL that it is actually implemented in any useful manner. Certificates certainly aren't.

I'm simply adding to the list as they occur to me...

share|improve this answer
An excellent start no doubt! Thanks for the answer. What port/package do you use/recommend for the CF? –  Mat Nadrofsky Dec 12 '08 at 16:14
Well I'm obviously going to recommend the Smart Device Framework. I may be heavily biased, but it's in use by tens of thousands so it must have a reasonable value. –  ctacke Dec 12 '08 at 16:17
All excellent except for caching frequently-used forms. I've found that to be more trouble than it's worth. –  MusiGenesis Dec 12 '08 at 16:44
Based on personal experience in most of these areas, I'd like to give this at least +5. And what you already know about .NET will generally prove to be almost true in CE. –  le dorfier Dec 12 '08 at 17:54
CoreCon is not an object. CoreCon is the transport layer that Studio uses for 'talking' to an attached device. –  ctacke Apr 30 '09 at 15:27
show 14 more comments

OpenNETCF is a great resource.

Their Smart Device Framework is a real must have when developing with the .NET Compact Framework, as so many of the Full framework features are missing [I think someone once said the .NET Compact Framework is a wrapper around NotImplementedException!]

share|improve this answer
In the vast majority of cases if you're developing without doing something with OpenNETCF you're probably doing it wrong! :) –  Quibblesome Jan 19 '09 at 11:42
Ine thing I'd caution about it using v. 1.4 - it's several years old now (3 IIRC?) and we've made a lot of changes and bug fixes since then. –  ctacke Jan 19 '09 at 20:16
@ctacke : cheers, I've updated (not sure how I managed to put such an old link in!) –  Mitch Wheat May 4 '09 at 10:51
add comment

This isn't specific to just Compact Framework devices, however it rears it's ugly head a lot more when developing on them due to resource contraints developing on a mobile platform.

Recently I came across a great post as part of a thread on managing memory leaks which helped me identify a leak I didn't know about in a bug when setting the DataGrid.DataSource in one of our mobile apps.

When binding a DataGrid, you should not directly use something like:

dgDataGrid.DataSource = dsDataSet;

As this creates a new CurrencyManager each time that doesn't properly get disposed of. Instead you want to bind the DataGrid to a BindingSource first in order to avoid the resource leak.

bsData.DataSource = dsDataSet;

dgDataGrid.DataSource = bsData;

Who knew? Scott Langham did in another post. Thanks Scott!

share|improve this answer
+1 because it's just wrong to downvote someone's answer to their own question. –  MusiGenesis Dec 12 '08 at 17:25
I was wondering about the downvote... is there little value in what I posted in your opinion or is it just not the right thread for me to mention it because it's not .Net CF specific.. not sure. I know it was a problem in our mobile app and accentuated by the fact it was on a mobile device. –  Mat Nadrofsky Dec 12 '08 at 19:48
No, your post was very valuable. No clue why someone would down-vote it, unless they thought you're not supposed to answer your own questions, which isn't correct. –  MusiGenesis Dec 12 '08 at 21:05
add comment

If you have to support multiple screen sizes/resolutions, form inheritance is an excellent way to do it. Basically you design your form to fit the standard 320x240 screen. To support a different screen size, you just add a new form, inherit from your custom form (instead of just Form), and then re-arrange the controls as necessary.

Another useful trick is to wrap the ShowDialog call in a way that lets you set the parent form's caption to "" temporarily - this keeps all the open forms in your application from showing up in the running programs list. Another way to enhance the wrapper is to PInvoke SetForegroundWindow with the handle of the parent window. This ensures that the parent will always re-appear after the child is closed; without this call, it's possible for other windows to be inserted in the z-stack above the parent form.

Watch out for encryption on the SD card. SqlCE will stop working altogether. Oracle Lite's behavior under encryption is much more sinister, since parts of it work and parts of it don't.

Avoid SqlCE RDA and merge replication. These would be fantastic tools if they worked reliably, but they don't in situations where the network connection can unexpectedly be dropped during replication (quite common in the WM world). This one bit me HARD with a production app. The MS support tech we dealt with was finally forced to acknowledge that it just doesn't work 100%. Actual quote: "just keep trying to replicate - they'll merge correctly eventually".

share|improve this answer
Thanks for the tips. Some great points made in here! We were going to steer clear of RDA on this project for sure. Also, we've written our own form manager so that we can push and pull forms from our own stack which seems to be working out so far and takes into account your advice. :) –  Mat Nadrofsky Feb 1 '09 at 13:33
I'd suggest starting with supporting 240x240 as a minimum resolution sing where are still a few wm devices that have it. –  Joel May 15 '09 at 21:10
@Joel: good point. I wouldn't want to piss off both of those guys! –  MusiGenesis Feb 25 '10 at 21:26
add comment

Just as an FYI, if you are upset about not having Compact Framework support in Visual Studio 2010 then go here and vote for it to be added in. (And spread the word)

MS has more or less abandoned existing feature requests in Connect. Please go to the new User Voice site to vote for this feature.

share|improve this answer
+1 - Yikes. Not a bad tip, "stick with VS2008 if you're into .Net CF" –  Mat Nadrofsky Sep 28 '10 at 14:00
add comment

Most out of the ordinary stuff requires direct call the Windows API through P/Invoke. I have found http://www.pinvoke.net/ to be a great resource for P/Invoke on both Win32 and Windows CE.

share|improve this answer
add comment
  • If you are planning to use Sql Server 3.5 Compact read this blog.
  • There are serious performance issues at SQL Server Compact and some code may be 100 times slower on the device compared to the desktop so always test your database code on the device.
  • Setup unit and performance / integration testing on the device. Also very few people actually do this, it's not that complicated and far overweights the costs.
  • If you deploy your code all the time use the network instead of ActiveSync. The easiest way is setting up a simple FTP server or TCP agent on the device.
share|improve this answer
Our "solution" to using SQLCE was to use SQLite. :) –  Mat Nadrofsky Mar 30 '09 at 17:31
add comment

Working with Compact Framework and SqlCe, there can be a lot of issues with performance, memory leaks and thread synchronisations.

Rules to abide by to minimise Compact Framework - SqlCe headaches.

  1. Use one SqlCe connection - you can use a locking mechanism on the connection to enable the use of one connection on multiple threads.
  2. Bulk Data inserts are slow because of the Sqlce Engine. Use direct table inserts, which has a similar performance benefit to writing directly to a text file.
  3. Dispose the SqlCe connection on close of the application. This makes sure all resources are cleaned up.
  4. Dispose all commands, datareaders etc after every call to the database. Using statements are your friend. Make sure reader objects are inside command using statements etc...
share|improve this answer
BulkInsert using ErikEJ's library is fast. See sqlcebulkcopy.codeplex.com –  B. Clay Shannon Dec 11 '13 at 18:18
add comment

OpenNet CF is worth looking into - even the free edition has a few useful libs - such as FTP, datagrid additional functionality etc; which is very helpful since CF lacks a lot of .net framework features.

share|improve this answer
I bet ctacke agrees. :) Thanks for the answer! –  Mat Nadrofsky Feb 1 '09 at 13:30
add comment

Unit Testing (TDD) is possible on .net cf. But there are issues.

You will be using MSTest. Not NUnit, MBUnit, XUnit.net, etc. MSTest.

You will need Visual Studio Professional (as near as I can tell). The easiest way to get started is to right-click on a method you would like to test, then select "Create Unit Test". This sets up the test project for you. Only create one test project. It doesn't like having multiple. Just do this to create the project and get all of the dependencies setup for you. Then create your own test classes.

Mock objects could be an issue. RhinoMocks, Moq, and TypeMock all depend on things that are not available in .net cf. Pex has a project calls Stubs that I'm still looking into. Pex is a Microsoft Research project. You you will end up creating custom fake objects instead.

Test are run on the device emulator. That means they have to be deployed. If you get a strange error when you first start up the test runner, you probably do not have .net 3.5 on the device emulator yet. First deploy your project, then run the tests again.

On the non-testing side: You do get LINQ to Objects and LINQ to XML. Both are a godsend. You can talk to a server via WCF, but you don't get all of the endpoints.

share|improve this answer
+1 - Hey thanks for the Q/A slant. We're getting to the Q/A phase on a major new mobile offering and links like this will help on this, our first time through the gauntlet on shipping a Windows Mobile product. –  Mat Nadrofsky Apr 29 '09 at 21:42
You can put a normal unit test project to unit test a compact framework (Smart Device) project. VS gives you a scary warning, but it is smooth sailing after that. –  Vaccano Sep 28 '10 at 20:39
add comment

When using a DataGrid you can sort it's contents via the column headers by using the following code originally posted on Chris Craft's blog:

using System.Windows.Forms;
using System.Data;

public static void SortDataGrid(object sender, System.Windows.Forms.MouseEventArgs e)
   DataGrid.HitTestInfo hitTest;
   DataTable dataTable;
   DataView dataView;
   string columnName;
   DataGrid dataGrid;

   // Use only left mouse button clicks.
   if (e.Button == MouseButtons.Left)
   // Set dataGrid equal to the object that called this event handler.
   dataGrid = (DataGrid)sender;

   // Perform a hit test to determine where the mousedown event occured.
   hitTest = dataGrid.HitTest(e.X, e.Y);

   // If the MouseDown event occured on a column header,
   // then perform the sorting operation.
   if (hitTest.Type == DataGrid.HitTestType.ColumnHeader)
      // Get the DataTable associated with this datagrid.
      dataTable = (DataTable)dataGrid.DataSource;

      // Get the DataView associated with the DataTable.
      dataView = dataTable.DefaultView;

      // Get the name of the column that was clicked.
      if(dataGrid.TableStyles.Count != 0)
         columnName = dataGrid.TableStyles[0].GridColumnStyles[hitTest.Column].MappingName;
         columnName = dataTable.Columns[hitTest.Column].ColumnName;

      // If the sort property of the DataView is already the current
      // column name, sort that column in descending order.
      // Otherwise, sort on the column name.
      if (dataView.Sort == columnName)
         dataView.Sort = columnName + " DESC";
         dataView.Sort = columnName;

private void dgDataGrid_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
   if(dgDataGrid.VisibleRowCount == 0) return;
   SortDataGrid(sender, e);
share|improve this answer
Actually the original original is from Alex Feinman: alexfeinman.com/download.asp?doc=GridDemo.zip –  ctacke Mar 30 '09 at 21:59
add comment
  • You will encounter a lot of Bugs and Limitations in .net cf. You will have to monkey patch them. its ugly but you will have no choice.

  • You will end up writing a lot of custom controls. As most of the controls in the framework don't support features that are commonly requested by clients. So its a good practice to create custom controls for each and every control you use from the start. Even though you might not have anything in them when you begin. You can add custom logic later on. Without having to modify a lot of existing code.

  • If you need validation you could use .net validation framework

  • Its a good idea to sperate your code everywhere in your App. You could use the MVC pattern. And if you choose to use it you can get a head start by using MobileMVC
  • If you need a rich UI tool kit you can look at Resco (google it).
  • VS Designer will be your arch enemy.

This is all that i can think of right now.

share|improve this answer
add comment

When doing anything with OutlookSession, always

  • instantiate it on the main (application) thread
  • execute against it on the main thread (I use a Control object to Invoke against)
  • and dispose of it within a decent timeframe (if you don't you'll have strange behavior in Pocket Outlook)
share|improve this answer
add comment

When working with Windows Mobile, if you don't want your form to be full screen you need to set the FormBorderStyle to None. If you don't then you will spend hours pulling out your hair wondering why it is resizing automatically to the full screen size (which is in fact a feature of Windows Mobile)

share|improve this answer
Yep. Waaaay back from 2004: blog.opennetcf.com/ctacke/2004/02/02/… –  ctacke Sep 22 '10 at 3:08
Is this only relevant for CF 2.0 or Windows Mobile 6? I can edit my answer to reflect this. –  havok Sep 22 '10 at 3:26
It's relevant to all WinMo platforms, regardless of language (you get the same behavior with a C++ app). –  ctacke Sep 22 '10 at 14:15
add comment
