Custom Controls Design Time Support Part 12: Adding SmartTag

One more advantage you get from building a custom designer for your custom controls is that you can add smart tag panel to add important most used properties and methods.

What is a Smart Tag?

aa

SmartTag is one of the new enhancement of VisualStudio 2005 design time and VS 2008 as well. Smart tags are menu-like user interface (UI) elements that supply commonly used design-time options. Most of the standard components and controls provided with the .NET Framework contain smart tag and designer verb enhancements. [more]

Some terminology before we start.

DesignerActionItem :  is a base class for all items on the Action List, a designer action item can be on of the following :

DesignerActionTextItem : Just an item with text does nothing used to give information only without any interaction with the user, can have a display name and a category.

DesignerActionHeaderItem : A special case of text item but written in bold , can have a display name and a category.

DesignerActionProeprtyItem : An item that represents a property, the property that is maps can have an Editor attribute to enhance the editing time (I talked about editors here and here), a property item has a Member Name (the property to me mapped), display name, category and a description (to be shown as a tooltip).

DesignerActionMethodItem : An item that represents a method, the method item has a constructor that accepts the DesignerActionList that the method will be added to, member name, display name, category, description and a boolean value to show this method as a designer verb(I talked about designer verbs here).

DesignerActionList: a collection of Items described above.

DesginerActionListCollection : a collection of Lists of items.

DesignerActionUIService: Manages the UI of the smart tag panel. Used to show, hide and refresh the panel when needed.

How to?

The sample I introduce here depends on the control I created the last two parts.

Add a designer.

Build a custom ActionList by extending the DesignerActionList class.

[code:c#]

public class UserControlDesignerActionList : DesignerActionList
{
     public UserControlDesignerActionList(UserControlDesigner designer)
          : base(designer.Component)
     {
          _designerActionUISvc = GetService(typeof(DesignerActionUIService)) as DesignerActionUIService;
          _controlDesigner = designer;
     }
}

[/code]

Put some properties and methods to be mapped by the action items.

[code:c#]

public Color BorderColor
{
    get
    {
        return _controlDesigner.BorderColor;
    }
    set
    {
        _controlDesigner.BorderColor = value;
        RefreshAll();
    }
}

public bool ShowBorder
{
    get { return _controlDesigner.ShowBorder; }
    set
    {
        _controlDesigner.ShowBorder = value;
        _designerActionUISvc.Refresh(this.Component);
    }
}

public Size Size
{
    get { return _controlDesigner.Control.Size; }
    set { _controlDesigner.Control.Size = value; }
}

public AnchorStyles Anchor
{
    get
    {
        return _controlDesigner.Control.Anchor;
    }
    set
    {
        _controlDesigner.Control.Anchor = value;
    }
}

public void MakeItRed()
{
    _controlDesigner.BorderColor = Color.Red;
    RefreshAll();
}

public void MakeItRandom()
{
    Random r = new Random();
    _controlDesigner.BorderColor = Color.FromArgb(r.Next(256), r.Next(256), r.Next(256));
    RefreshAll();
}

private void RefreshAll()
{
    _controlDesigner.Control.Refresh();
    _designerActionUISvc.Refresh(_controlDesigner.Component);
}

[/code]

And now override the GetSortedItems method a return a customized list.

[code:c#]

public override DesignerActionItemCollection GetSortedActionItems()
{
    DesignerActionItemCollection col = new DesignerActionItemCollection();

    DesignerActionHeaderItem hi = new DesignerActionHeaderItem("Border settings", "Border");
    col.Add(hi);

    DesignerActionPropertyItem pi = new DesignerActionPropertyItem("ShowBorder", "Show the border", "Border", "Check to show the border");
    col.Add(pi);

    if (ShowBorder)
    {
        DesignerActionPropertyItem pi2 = new DesignerActionPropertyItem("BorderColor", "Choose Color", "Border", "Choose a color from editor");
        col.Add(pi2);

        DesignerActionMethodItem mi = new DesignerActionMethodItem(this, "MakeItRed", "Make a Red border", "Border", "Click to change the border to Red", true);
        col.Add(mi);

        DesignerActionMethodItem mi2 = new DesignerActionMethodItem(this, "MakeItRandom", "Random Color", "Border", "Click to get a random border color", true);
        col.Add(mi2);
    }

    DesignerActionHeaderItem hi2 = new DesignerActionHeaderItem("Layout settings", "Layout");
    col.Add(hi2);

    DesignerActionPropertyItem pi3 = new DesignerActionPropertyItem("Size", "Size", "Layout", "Set the Size");
    col.Add(pi3);

    DesignerActionPropertyItem pi4 = new DesignerActionPropertyItem("Anchor", "Anchor", "Layout", "Choose anchor style from editor");
    col.Add(pi4);

    return col;
}

[/code]

Finally, get back to the Designer class and override the ActionLists property and an instance of our custom created ActionList.

[code:c#]

public override DesignerActionListCollection ActionLists
{
     get
     {
         DesignerActionListCollection d = new DesignerActionListCollection();
         d.Add(new UserControlDesignerActionList(this));
         return d;
      }
}

[/code]

And thats it. The final result looks like this.

Final result DesignerActionList

More on this : http://msdn2.microsoft.com/en-us/library/ms171829(VS.80).aspx

Download the sample source code UserControlDesigner.cs (7.16 kb)

4 thoughts on “Custom Controls Design Time Support Part 12: Adding SmartTag”

  1. You’re great !!!!!
    I’ve been looking for description on Design Time.
    I think your articles are the best from what i’ve found.

    Maby try publishing them somewere else… (Codeproject, Codeguru…)
    Is there any chance to get printer-friendly version here ?:>
    If there is, please post your ariicles about design time zipped in your next posts, I like (and I think not only me :D) to have good knowledge on paper 😀
    THX again, you’ve been delicioused 😀

  2. Thank you for this article! Reviewed huge number of articles – the best this article. Now, my problem is solved. Thanks again!

Leave a Reply

Your email address will not be published. Required fields are marked *