Некоторое время назад у меня было похожее требование, и я сделал нечто похожее на:
[ParseChildren(true, "Templates")]
public class TypedRepeater : CompositeDataBoundControl
{
[
PersistenceMode(PersistenceMode.InnerProperty),
Browsable(false),
MergableProperty(false)
]
public TypedTemplateCollection Templates
{
get;
}
защищенный TypedTemplate GetTemplate (объект dataItem)
{
if (dataItem == null)
{
вернуть ноль;
}
foreach (шаблон TypedTemplate в шаблонах)
{
Тип itemType = dataItem.GetType ();
if (dataItem.IsAssignableFrom (template.Type))
{
шаблон возврата;
}
}
вернуть ноль;
}
protected TypedTemplateRepeaterItem CreateItem(int index, object dataItem, bool dataBinding)
{
TypedTemplateRepeaterItem repeaterItem = new TypedTemplateRepeaterItem();
if ((!dataBinding) && (ViewState[string.Format("TemplateIxc_{0}", index)] is int))
{
int _template = (int)ViewState[string.Format("TemplateIxc_{0}", index)];
if ((_template >= 0) && (_template < Templates.Count) && (Templates[_template].ItemTemplate != null))
{
Templates[_template].ItemTemplate.InstantiateIn(repeaterItem);
}
else
{
DefaultTemplate.InstantiateIn(repeaterItem);
}
}
else if (dataBinding)
{
TypedTemplate template = GetTemplate(dataItem);
ITemplate itemTemplate = DefaultTemplate;
if (template != null)
{
itemTemplate = template.ItemTemplate;
ViewState[string.Format("TemplateIxc_{0}", index)] = Templates.IndexOf(template);
}
else
{
ViewState[string.Format("TemplateIxc_{0}", index)] = -1;
}
repeaterItem.DataItem = dataItem;
repeaterItem.DataItemIndex =
repeaterItem.DisplayIndex = index;
itemTemplate.InstantiateIn(repeaterItem);
repeaterItem.DataBind();
repeaterItem.DataItem = null;
}
return repeaterItem;
}
protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
{
int count = 0;
if (dataSource != null)
{
foreach (object dataItem in dataSource)
{
TypedTemplateRepeaterItem repeaterItem = CreateItem(count, dataItem, dataBinding);
Controls.Add(repeaterItem);
count++;
}
}
return count;
}
}
, где TypedTemplateCollection является StateManagedCollection класса TypedTemplate:
[ParseChildren(true, "ItemTemplate")]
public class TypedTemplate
{
public Type Type
{
get { return Type.GetType(TypeName); }
}
[
PersistenceMode(PersistenceMode.Attribute),
Browsable(true),
DefaultValue("")
]
public string TypeName
{
get;
set;
}
[
PersistenceMode(PersistenceMode.InnerProperty),
Browsable(true),
DefaultValue(typeof(ITemplate), null),
TemplateContainer(typeof(TypedTemplateRepeaterItem))
]
public ITemplate ItemTemplate
{
get;
set;
}
}
и TypedTemplateRepeaterItem:
public class TypedTemplateRepeaterItem : WebControl, INamingContainer, IDataItemContainer
{
#region IDataItemContainer Members
public object DataItem
{
get;
set;
}
public int DataItemIndex
{
get;
set;
}
public int DisplayIndex
{
get;
set;
}
#endregion
}