Design Time Support
Recently, I have been doing a lot of work in making controls have some design time support, I am creating composite controls, and it's a whole different world from user controls i have to say :-)
I have made them before, but really only used them in code or in things i needed and jsut manipulaed, never worrying much about designer support, becuase the time to make as opposed the benefit of developer candy was not worth it.
However, creating controls for others is a different story, and the work need be done properly i say. When making controls that other people are going to use, you especially when they will have little or no contact with you and honestly you wish to do as little support as possible for your products, so you should aim to have
a) bug free code.. we all do that, right ? :-) we all have our try's and catch's and effiecient precompiler directives around some helpful debug code.
b) the easier to use.... the quicker to do more with less tasks... the less curiosity people have as to what else the control offers ;-) so they don't stumble upon your bugs anyway.
anyway, my post was about designer support... and i ran on a tangent, luckily this is my blog, and if you read this far... i am truely honored.
First, I will point you to this article (it's good, short, helpful, read it if you are begining with designer support) : http://www.codeproject.com/useritems/design-time-integration.asp
Now.... you can put alot of work into editing the properties of controls at run time.... or you can find the important things early on to understand, and the rest will fall into place as you need it. This is what noone told me... so ill tell you.
Start with: Action Lists
action lists are new in 2005, are the little arrows to the right top of a control in the designer, like template editing, and provide the quickest, easiest way to modify properties in the desinger ( exculde the property window for now.... althoguh its nice for a lot of things, it gets much more complicated when you hit collections and things, so... )......
make your design fun with action lists... and modify things easy... watch ;-)
the following chunk of code, initializes the action list, and adds a combo box with the values from the orientation enum to them using an enumconverter for the property.
1: public class TabControlDesigner : CompositeControlDesigner
2: { 3: // you end up refering to component alot, so make a local var.
4: private TabControl tabControl;
5: public override void Initialize(IComponent component)
6: { 7: base.Initialize(component);
8:
9: tabControl = (TabControl)component;
10: }
11:
12: // Action Lists start empty, so we need to
13: // override, and add our component to the list.
14: public override DesignerActionListCollection ActionLists
15: { 16: get
17: { 18: DesignerActionListCollection actionLists = new
19: DesignerActionListCollection();
20: // Copy all the action lists from the base class
21: actionLists.AddRange(base.ActionLists);
22: // Add our own action list
23: actionLists.Add(new
24: TabControlActionList(tabControl));
25: return actionLists;
26: }
27: }
28:
29: // I found it very helpful to have a litte class to
30: // handle my action lists neatly, this is not a requirement.
31: // you can find more 'straight foward wasy' online.
32: private sealed class TabControlActionList : DesignerActionList
33: { 34: private TabControl _TabControl;
35:
36: // Create a property Orientation
37: // Using TypeConverter for enum
38: // we will get a combo box with the values in
39: // System.Web.UI.Orientation
40: [TypeConverter(typeof(EnumConverter))]
41: public Orientation Orientation
42: { 43: get
44: { 45: return _TabControl.Orientation;
46: }
47: set
48: { 49: PropertyDescriptor propDesc =
50: TypeDescriptor.GetProperties(typeof(TabControl))["Orientation"];
51: propDesc.SetValue(_TabControl, value);
52: }
53: }
54:
55: // Override getsortedactions, and add anything you want.
56: public override DesignerActionItemCollection GetSortedActionItems()
57: { 58: DesignerActionItemCollection items = new
59: DesignerActionItemCollection();
60: items.Add(new
61: DesignerActionPropertyItem("Orientation", "Orientation:")); 62: return items;
63: }
64:
65: }
66: }
Regions:
Regions are like little html hotspots. they allow for editable, and clickable areas in the designer. you can create them by attaching to the render html of the control, and placing some additional properties.
The following are the two key methods for working with and assigning regions.
1: public override string GetEditableDesignerRegionContent(EditableDesignerRegion region){} 2:
3: public override void SetEditableDesignerRegionContent(EditableDesignerRegion region, string content){} 4:
Lastly in the designers create childcontrol, i wrap my control parts in an html table and assign attibutes
tc.Attributes[
DesignerRegion.DesignerRegionAttributeName] = i.ToString();
then in the other two methods you work with the pieces of the puzzle ;-)
finally in my getdesigntimehtml... i set my editable regions with something like.
1: public override String GetDesignTimeHtml(DesignerRegionCollection regions)
2: {
3:
4: // Create an editable region and add it to the regions
5: // the design region name will take CONTENT_PREFIX as prefix and the index
6: // of the current active tab.
7:
8: EditableDesignerRegion editableRegion =
9: new EditableDesignerRegion(this,
10: CONTENT_PREFIX + tabControl.CurrentDesignTab, false);
11: regions.Add(editableRegion);
12:
13: // Set the highlight for the selected region
14: regions[tabControl.CurrentDesignTab].Highlight = true;
15:
16: // Use the base class to render the markup
17: return base.GetDesignTimeHtml();
18: }
another intersint thing to pay attention to with designer stuff,
is the changes (missing pieces) of a page life cycle that you may
need to account for in your control logic. In somce cases it may be very difficult to
render some controls to the designer, and it may be easier to replace them wih some other
reactive html like regions and actionlists in the designer.
The same sort of thing when you have an empty control, or new control, there probably
wont be data or initialized properties yet, so you will come accross designer exceptions.
Become friends with : GetErrorDesignTimeHtml
OK, that is enough rambling for now, I think I will probably do a few more posts
on designer support, and composite controls in general over the comming weeks/months depending
on my available time. Perhaps my writing form will get better too ;-)