preload
Nov 12

When developing Windows Mobile applications in Visual Studio creating user controls or custom controls will often help you get a better application and decrease your development time. Often you will have problem using your user controls or custom controls in the Visual Studio designer. Forms using your controls will not show at all in the designer and sometimes Visual Studio will shut down because of this (happens often if you are referring to external .dll in the user control or custom control).

I will walk you through a simple example on how you can achieve this with out any problems at all.

I will use a simple example where I have created a Header user control that is referring to the Microsoft.WindowsMobile.dll and Microsoft.WindowsMobile.Status.dll. Then I have a simple Form that I will use the designer to append the Header to and make sure the Visual Studio designer still works.

I am using Visual Studio 2008, Windows Mobile 6 Professional SDK and .Net Compact Framework 3.5 for this example.

The Header is just a simple user control where the width is covering the whole screen width and the height is set to 40 pixel. To this user control I have added a button covering the whole user control. This header will show number of missed calls:

Header.cs

using System;
using System.Windows.Forms;
using Microsoft.WindowsMobile.Status;

namespace DesignTimeExample
{
    public partial class Header : UserControl
    {
        public Header()
        {
            InitializeComponent();
            SystemState missedCalls = 
            new SystemState(SystemProperty.PhoneMissedCalls);
            missedCalls.Changed += MissedCallsChanged;
            SetMissedCalls();
        }

        private void MissedCallsChanged(object sender, EventArgs e)
        {
            SetMissedCalls();
        }

        private void SetMissedCalls()
        {
            _missedCalls.Text = "Missed calls: " 
           + SystemState.PhoneMissedCalls.ToString();
        }
    }
}

The first thing I need to do is to add the Header user control to the ToolBox so I easily can drag & drop it on to my Form. I right click in the ToolBox and chose “Add Tab” and I create a new tab called User Control. Then I right click on my newly created Tab and click “Choose items”. I browse to my project, goes to the bin/debug folder and choose the project .exe file. When doing so all custom controls and user controls are added to the list and you simply click “OK”. I can now find Header under the User Control tab I created earlier.

This is great I can now drag & drop my user control on to the Form. But the user control is not displayed correctly. The only thing that is displayed in the designer now is the area the user control will cover and the namespace of the user control on top of this.

DesignTime not working

To be able to make this user control appear correctly in the Form we need to add it to the Design-Time Attributes for the project. Right click on your project and add new item, choose Design-Time Attribute File and add this to your project.

DesignTime attributes

Then you need to add the class name for the Header in this file and set DesktopCompatible to true.

DesignTimeAttributes.xmta

<?xml version="1.0" encoding="utf-16"?>
<Classes xmlns="http://schemas.microsoft.com/VisualStudio/2004/03/SmartDevices/XMTA.xsd">
  <Class Name="DesignTimeExample.Header">
    <DesktopCompatible>true</DesktopCompatible>
  </Class>
</Classes>

You should also right click the Header class and choose View Class Diagram, this generates a class diagram called ClassDiagram1.cd and is placed on root. I rename it to HeaderClassDiagram.cd. The Class Diagram will also help the Visual Studio designer to know what to draw.

When all this is done: Close the design tab for the Form and rebuild your project, then try to open it. Now the designer does not work at all and displays an error message followed by that Visual Studio has encountered a problem and needs to close.

DesignTime error

DesignTime needs to close

This is because I am using the external .dll to get the missed calls. If you have a normal user control with out and special .dll references it would most likely work now.

To be able to make the designer work with user controls referring to external .dll we need to do one more thing and this is to actually block out the “harmful” code when running in design mode. I go to my project properties –> build and add DesignTime to conditional compilation symbols. Conditional compilation symbols are now set to: PocketPC;DesignTime.

DesignTime

I go back to my Header source code and block out the code by using #if DesignTime

Header.cs with DesignTime support

using System;
using System.Windows.Forms;
using Microsoft.WindowsMobile.Status;

namespace DesignTimeExample
{
    public partial class Header : UserControl
    {
        public Header()
        {
            InitializeComponent();

            #if DesignTime
            _missedCalls.Text = "Missed calls: 0";
            #else
            SystemState missedCalls = 
            new SystemState(SystemProperty.PhoneMissedCalls);
            missedCalls.Changed += MissedCallsChanged;
            SetMissedCalls();
            #endif
        }

        private void MissedCallsChanged(object sender, EventArgs e)
        {
            SetMissedCalls();
        }

        private void SetMissedCalls()
        {
            _missedCalls.Text = "Missed calls: " 
             + SystemState.PhoneMissedCalls.ToString();
        }
    }
}

Then I rebuild my project and I try to open my Form in the designer and I can see that the designer are working just the way it should now.

DesignTime working

The drawback now is that you need to remember to add or remove the DesignTime from the conditional compilation symbols depending on if you are going to use the designer or run the application. Of course you can create a new Configuration for the DesignTime so you do not need to manually add or remove this each time.

Remember that for each time you have done any changes and will open the designer to see if it works it can be a good thing to close all tabs and rebuild your project first. That way you are sure that the designer tab are opened with the new changes.

Follow me on twitter @PerOla

Share & enjoy
You can subscribe to my comments feed to keep track of new comments.

1 Comment to “Using user controls with external .dll references in Visual Studio designer”

  1. Mauricio de Sousa Coelho says:

    Hi,

    I already had exactly this same problem and I used a similiar solution, follow my code:

    static public bool IsDesignMode()
    {
    return AppDomain.CurrentDomain.FriendlyName.Contains(“DefaultDomain”);
    }

    Instead I use any define (#if DesignTime), I use this function than I don´t need to change the define in the project properties.

    I hope I could help someone
    Mauricio de Sousa Coelho

No Pingbacks to “Using user controls with external .dll references in Visual Studio designer”

Leave a Reply

Subscribe to my comments feed

Subscribe to my feeds Follow me on Twitter
DZone MVB