The purpose of this essay is recording the key steps if you hope to create control and hope it support Template and edit the templates at Designer time.
1. Create a class derives from Control class,INameContainer,IDataItemContainer. This step is a little same as RepeatItem(it is an instance to bind data that you can iterate DataSource). Such as follows:
[ToolboxItem(false)] public class myItem :Control, IDataItemContainer { private object _currentItem; private int _itemIndex; public myItem(int itemIndex,object item) { _itemIndex = itemIndex; _currentItem = item; } #region IDataItemContainer Members public object DataItem { get { return _currentItem; } } public int DataItemIndex { get { return _itemIndex; } } public int DisplayIndex { get { return _itemIndex; } } #endregion }
2. Override PerformDataBinding method to bind data from DataSource and present the data with the instance of myItem class.
protected override void PerformDataBinding(IEnumerable data) { this.Controls.Clear(); createTemplateControls(TemplateType.HeaderTemplate, -1, null); if (DataSource != null) { IEnumerator iList = data.GetEnumerator(); int index = 0; while (iList.MoveNext()) { myItem itemObj = createTemplateControls(TemplateType.ItemTemplate, index, iList.Current); ItemEventArgs arg = new ItemEventArgs(itemObj); this.OnDataBound(arg);//Raise Event itemObj.DataBind();//Raise DataBind() so that all the controls in Template support databinder. index += 1; } } createTemplateControls(TemplateType.FootTemplate, -2, null); } private myItem createTemplateControls(TemplateType type,int itemIndex,object currentItem) { ITemplate template = null; switch (type) { case TemplateType.HeaderTemplate: template = HeaderTemplate; break; case TemplateType.ItemTemplate: template = ItemTemplate; break; case TemplateType.FootTemplate: template = FootTemplate; break; default: template = HeaderTemplate; break; } myItem headItem = null; if (template != null) { headItem = new myItem(itemIndex, currentItem); template.InstantiateIn(headItem); this.Controls.Add(headItem); } return headItem; } }
3. To support editable Template at designer time, we'd better to create particular ControlDesigner.
public class MyRepeaterDesigner : DataBoundControlDesigner { public override void Initialize(IComponent component) { base.Initialize(component); SetViewFlags(ViewFlags.TemplateEditing, true); } public override string GetDesignTimeHtml() { MyRepeater control = Component as MyRepeater; if (control != null) { if (control.ItemTemplate == null) { return CreatePlaceHolderDesignTimeHtml("You can go through the 'Righ click' or click the 'Smart tag' to edit 'Item/Header/Foot template '"); } } return base.GetDesignTimeHtml(); } TemplateGroupCollection templateGroups; public override TemplateGroupCollection TemplateGroups { get { if (templateGroups == null) { templateGroups = base.TemplateGroups; TemplateGroup head_template = new TemplateGroup("HeaderTemplate"); head_template.AddTemplateDefinition(new TemplateDefinition(this, "Header", Component, "HeaderTemplate", false)); templateGroups.Add(head_template); TemplateGroup item_template = new TemplateGroup("ItemTemplate"); item_template.AddTemplateDefinition(new TemplateDefinition(this, "Item", Component, "ItemTemplate", false)); templateGroups.Add(item_template); TemplateGroup foot_template = new TemplateGroup("FootTemplate"); foot_template.AddTemplateDefinition(new TemplateDefinition(this, "Foot", Component, "FootTemplate", false)); templateGroups.Add(foot_template); } return templateGroups; } } }