Mooseworks Software, LLC
Controls That Work

Compact Framework Custom Control Design Support in Visual Studio 2005


Visual Studio 2005 has changed the way Compact Framework controls provide designer support. The good news is that you no longer have to create a design time dll. The bad news is that to provide complete design support (descriptions, default values, type converters, editors, etc.) you need to create an extensive XML file that turns into a design time dll. This article will discuss providing these features using a simple graph control as an example. There are some other good references available at:

The graph at design time will look like the image below.

The list of properties is shown in the table below.

Property

Type

MajorGrid Mooseworks.GI.Grid
PlotBackgroundColor System.Color
Plots Mooseworks.GI.Plot[]
XAxis Mooseworks.GI.XAxis
XValues System.Double[]
YLeftAxis Mooseworks.GI.YAxis
YValues System.Double[,]

Note that some of these properties are not standard types. We will look at their design time support later. Let us begin at the start. First, create a Smart Device Pocket PC 2003 Control Library project. There are two ways to add properties to the control. Well start with the Class Designer approach, then well look at the code it generates which we could do manually as well. To start Class Designer, right click the controls node in Solution Explorer (MwSimpleGraph in our case), and select View Class Diagram. ClassDiagram1.cd will be displayed like the image below.

Select the SimpleGraph object and then select the Class Details tab below. On this tab you can create Properties, Methods, Events and Fields. Well create the PlotBackgroundColor property first as shown below.

We can enter the property name, type, modifier and summary directly. In the Property Browser, we can go farther than that. In Visual Studio 2003, we could apply attribute tags to the property. We can do the same thing here, but we can use the Custom Attributes item in the Property Browser to do so. Also, the attributes do not end up in our source code file, but are placed in a separate XML file which we will look at in a little while. The Custom Attributes property has an editor as shown below. We have filled in our attributes for the PlotBackgroundColor so that it will be fully described at design time.

So, what code did this generate? In our Graph.cs file, the PlotBackgroundColor property looks like:

/// <summary>
///
The background color of the plot area
/// </summary>
public
Color PlotBackgroundColor
{
     get
     {
          throw new System.NotImplementedException();
     }
     set
     {
     }
}

There are no great surprises here. We do have to fill in the implementation, obviously. Where did our attributes go? Since this source file is used to build the runtime control, and there is no design time during runtime, the attributes are not included in this source file. They are put into an XML file, DesignTimeAttributes.xmta, which looks like:

<?xml version="1.0" encoding="utf-16"?>
<
Classes xmlns="http://schemas.microsoft.com/VisualStudio/2004/03/SmartDevices/XMTA.xsd">
    <Class Name="Mooseworks.GI.SimpleGraph">
   
    <Property Name="PlotBackgroundColor">
            <Browsable>true</Browsable>
            <DesignerSerializationVisibility>
                DesignerSerializationVisibility.Visible
            </DesignerSerializationVisibility
>
            <DefaultValue>
                <
Type>System.Drawing.Color</Type>
                <Value>System.Drawing.Color.Linen</Value>
       
    </DefaultValue>
            <
Category>Appearance</Category>
            <Description>The background color of the plot area</Description>
        </Property>
    </
Class>

You can see that all our attribute information is here. If we compile now, we will be given two files, MwSimpleGraph.dll and MwSimpleGraph.PocketPC.asmmeta.dll. MwSimpleGraph.PocketPC.asmmeta.dll contains the design time attributes.

Next, well work with the more complex property types. The MajorGrid property is a Mooseworks.GI.Grid type. This type has two properties, Visible and Color. We want the user to be able to set the visibility and color of the major grid at design time by allowing the MajorGrid to expand in the property browser so that its properties are shown. This is shown below.

We can do this by applying the ExpandableObjectConverter to the MajorGrid property, and by applying attributes to the Grid class. The attributes are added to the DesignTimeAttributes.xmta file just as they were for the PlotBackgroundColor property. For the MajorGrid property, we define the TypeConverter as an ExpandableObjectConverter. We also set the browsable, serialization, category and description attributes. The XML is shown below.

<Property Name="MajorGrid">
     <
Browsable>true</Browsable>
     <DesignerSerializationVisibility>
        DesignerSerializationVisibility.Visible
    </
DesignerSerializationVisibility
>
     <TypeConverter>
          System.ComponentModel.ExpandableObjectConverter, System,
          Version=2.0.0.0, Culture=neutral,
          PublicKeyToken=b77a5c561934e089
     </TypeConverter>
     <
Category>Appearance</Category>
     <Description>The control's major grid</Description>
</Property>

We also need to add the Grid class to the attributes file. This XML looks like:

<Class Name="Mooseworks.GI.Grid">
     <TypeConverter>
          System.ComponentModel.ExpandableObjectConverter, System,
          Version=2.0.0.0, Culture=neutral,
          PublicKeyToken=b77a5c561934e089
     </TypeConverter>
     <
DesktopCompatible>true</DesktopCompatible>
     <Property Name="Visible">
          <Browsable>true</Browsable>
          <Description>Determines whether the grid is visible or hidden</Description>
          <DefaultValue>
              <
Type>System.Boolean</Type>
              <Value>false</Value>
          </DefaultValue>
          <
NotifyParentProperty>true</NotifyParentProperty>
     </Property>
     <
Property Name="Color">
          <Browsable>true</Browsable>
          <Description>The color of the grid</Description>
          <DefaultValue>
              <
Type>System.Drawing.Color</Type>
              <Value>System.Drawing.Color.Gray</Value>
          </DefaultValue>
          <
NotifyParentProperty>true</NotifyParentProperty>
     </Property>
</
Class>

The XAxis and YLeftAxis properties are handled in a similar manner. If you look at the code the designer generates for the graph in an application you will notice that the Expandable Object Converter creates code that is, well, expansive. It creates an instance of each object, and then sets properties one by one. CF form load is slow enough without this. To solve this problem, we've created a custom type converter in the MwSimpleGraphEditor project. The key method in the type converter is the ConvertTo method. This allows us to specify the object's constructor to be used. The parameters in the constructor can take care of setting the object's properties, so more lines of code are not necessary. The Plots property is an array of Plot objects. The Plot class has the custom PlotTypeConverter applied to it, but the Plots property has the CollectionConverter applied as its type converter. This provides us with a nice dialog to add and remove plots, and set their individual properties at design time. You can see because Plots is a collection, this can save quite a bit of initialization code. The dialog is shown below.

So now all of our properties have a good design time presentation. The control can be added to the toolbox in the same way a desktop control would be, just select the controls assembly, not the asmmeta.dll. So we no longer have to worry about adding the designer dll to the toolbox, and we dont have to worry about setting up the Designer directory structure. If we add the control to the toolbox right now, however, the bitmap is the default gear. Thats not what we want. Well first add the desired 16 x 16 bitmap to the project, and set its Build Action to Embedded Resource. The bitmap name must be the same as the control, and the default namespace of the project must be the same as the control namespace. Given these conditions, the bitmap will be picked up automatically, even without ToolboxBitmap attribute.

Our control looks pretty good now. Wed like to do one more thing to step up its usability, though. We want to add a property pages dialog for the entire control. Our pages are shown below.

To do this we create an editor that derives from ComponentEditor, and we set the Editor attribute of the class to that editor as shown below.

<Editor>
    <
Type>Mooseworks.GI.SimpleGraphEditor, MwSimpleGraphEditor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=15EF1E3443EA1F6B</Type>
    <
BaseType>System.ComponentModel.ComponentEditor, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089</BaseType>
</Editor>

Easy, right? Theres just one little problem. In order for the environment to find our editor, it must be signed and put into the GAC. Thats not a problem. We want to be able to communicate back and forth to control in order to get and set its properties, so we would like to have a reference to the control in our editor. Since the editor is signed, the control must be signed as well, since it will be a reference of our editor. This isnt a problem either. We can sign the control in the same way. Now, we can add the control to the toolbox, and thats where the problem occurs. The signed control doesnt appear to add well. I have seen variations of this where an error complaining that the asmmeta dll is not signed, so it doesnt match the control. I have also seen cases where no error occurs, but the control is not added. The article by Xin Yan indicates that the control should be signed, but the source associated with the control seems to have the same sort of inconsistent behavior. I assume that this is a beta problem, and it will be fine in the release version, but until then we have a large Reflection exercise. The source code of our editor shows the Reflection approach for those who are interested. (Note: The signing issue seems to have improved in the release version. Compact Framework 2.0 signed controls work fine in the toolbox. CF 1.0 controls still seem to have issues, however.)

One last note. If you are using imports of unmanaged dlls or API calls, you should add the DesktopCompatible attribute with a value of true to the class. You should also assure that import calls of device specific dlls do not occur while in design mode.

Download Source Code

Check out our full featured 2005 Graph Control, or Trend Graph Control. Download the Graph Demo or the TrendGraph Demo. Check out these features:

  • Bar, Line, Area, Scatter, Line and Symbol or combination plot types
  • Customizable data point symbols - preset symbols or your images
  • Graph Legend with circular or square symbols
  • Multiple X and Y data series
  • Right and Left Y axes
  • Scrollable axes
  • Logarithmic, inverted and normal axes in any combination
  • DateTime mode for X-Axis data
  • Zoom mode. The user can outline an area on the graph with the pen, and when the pen is lifted, the graph will zoom onto that area. Zooming in can be done an unlimited amount of times. Menus are available for zooming out. Just tap outside the graphs plot area.
  • Auto scaling
  • User moveable marker lines with events
  • Plot alarm settings - plot will change colors in alarm regions
  • Title and Axes Labels
  • Cursor event
  • Text File and Bitmap File Export
  • Enter an unlimited number of data series
  • Data can be entered as two arrays (X and Y data) or as one combined array
  • Full customization:
    • Title font and color
    • Legend location, labels, fonts and colors
    • Axis labels, precision, fonts and colors
    • Major and minor tick mark spacing and colors
    • Major and minor grid colors and visibility
    • Auto or manual scaling
    • Colors for each individual plot
    • Border colors width, and styles (3D, single, none)
    • Chart background and plot background colors
    • Owner drawing capability for drawing marker lines, image backgrounds, etc.
  • Property pages allow easy design time customization
  • 100% native .Net Compact Framework - Windows CE and PocketPC compatible.
Products
 Graph
 Trend Graph
 Visual Dashboard
 Instrumentation
 User Entry
 Email
Download Demos
 Graph
 Trend Graph
 Visual Dashboard
 Instrumentation
 User Entry
 Email
Support
 Contact
Testimonials
 Testimonials
 Awards
Articles
 VS2005 Control Design
 Windows CE Printing
 Links
About Us
 Home
 Contact
 News
 Legend