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?
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.
More on this : http://msdn2.microsoft.com/en-us/library/ms171829(VS.80).aspx
Download the sample source code UserControlDesigner.cs (7.16 kb)
Leave a Reply