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;
}
}
}