C# 绑定列表<;复合控制>;转发器
我有一个生成的自定义控件集合,这些控件扩展了CompositeControl,定义为:C# 绑定列表<;复合控制>;转发器,c#,asp.net,repeater,C#,Asp.net,Repeater,我有一个生成的自定义控件集合,这些控件扩展了CompositeControl,定义为: [持久化子项(true)] [ToolboxData(“”) 公共类ContractControl:CompositeControl { 私有int-d=0; 私有合同tileControl tileControl=null; private ContractDetailControl detailControl=null; 私有HtmlGenericControl contractMainDiv=null;
[持久化子项(true)]
[ToolboxData(“”)
公共类ContractControl:CompositeControl
{
私有int-d=0;
私有合同tileControl tileControl=null;
private ContractDetailControl detailControl=null;
私有HtmlGenericControl contractMainDiv=null;
公共整数收缩
{
获取{返回this.construcd;}
设置{this.construcd=value;}
}
公共合同TileControl TileControl
{
获取{返回this.tileControl;}
设置{this.tileControl=value;}
}
公共合同详细控制详细控制
{
获取{返回this.detailControl;}
设置{this.detailControl=value;}
}
公共合同管理()
{
this.contractMainDiv=新的HtmlGenericControl(“div”);
this.contractMainDiv.ID=“contractMainDiv”;
this.contractMainDiv.Attributes.Add(“class”,“contractMain”);
}
#区域保护覆盖无效OnPreRender(EventArgs e)
受保护的覆盖无效OnPreRender(EventArgs e)
{
基于预渲染(e);
//CreateChildControls();
}
#端区
#区域保护覆盖无效CreateChildControls()
受保护的覆盖无效CreateChildControls()
{
base.CreateChildControls();
如果(tileControl!=null)
{
this.contractMainDiv.Controls.Add(tileControl);
}
if(detailControl!=null)
{
this.contractMainDiv.Controls.Add(detailControl);
}
this.Controls.Add(contractMainDiv);
//base.CreateChildControls();
}
#端区
受保护的覆盖无效加载(事件参数e)
{
基础荷载(e);
CreateChildControls();
}
受保护的覆盖无效OnInit(事件参数e)
{
基础荷载(e);
ensureChildControl();
}
}
其中ContractTileControl
和ContractDetailControl
是从CompositeControl
派生的另一个自定义控件
当我将它们添加到asp:PlaceHolder
控件集中时,它们的渲染效果很好,但当我定义一个中继器时,如:
把他们绑在上面:
private void FillContractPlaceHolder()
{
列表控件=新列表();
foreach(合同列表中的KeyValuePair对)
{
标签CustomerNameBL=新标签();
customerNameLbl.ID=“customerNameLbl”;
customerNamebl.CssClass=“customerName”;
customerNamebl.Text=pair.Key.Name;
contractListPlaceHolder.Controls.Add(CustomerNameBL);
foreach(TFS成对合同价值)
{
ContractStatusBarControl状态=新ContractStatusBarControl();
status.WidthPercent=GetFillPercent(contract.NumberOfTasks,contract.NumberOfFinishedTasks);
字符串[]contractNameParts=Regex.Split(contract.contract.Name,@“[A-Z]{3}-[0-9|A-Z]{2}-[0-9|A-Z]{2}”,RegexOptions.IgnoreCase);
ContractDetailControl detail=新的ContractDetailControl();
detail.ContractName=contractNameParts.Last();
detail.DateStarted=contract.StartDate;
detail.DateFinished=contract.FinishDate;
detail.StatusBar=状态;
ContractTileControl磁贴=新ContractTileControl();
Match Match=Regex.Match(contract.contract.Name,@“[A-Z]{3}-[0-9|A-Z]{2}-[0-9|A-Z]{2}”,RegexOptions.IgnoreCase);
如果(match.Value.Length!=0)
{
tile.ContractNumber=match.Value;
}
tile.ContractTasksFinished=contract.NumberOfFinishedTasks;
tile.ContractTasksTotal=contract.NumberOfTasks;
ContractControl=新ContractControl();
contractControl.ContractID=contract.contract.Id;
contractControl.TileControl=平铺;
contractControl.DetailControl=详细信息;
//contractListPlaceHolder.Controls.Add(contractControl);
控件。添加(contractControl);
}
}
myRepeater.DataSource=控件;
myRepeater.DataBind();
}
创建表,但只有
ContractControl
的非复合部分contractMainDiv
被呈现,因为中继器坚持tileControl
和detailControl
都为空,即使它们被正确地设置为各自类型的实例。当中继器
被数据绑定时,它会为数据源中的每个项目创建项目模板
的实例,将其数据项
设置为数据源中的项目,然后数据绑定子项
在这种情况下,数据源中的项是ContractControl
的一个实例,而ItemTemplate
没有数据绑定,因此对于添加到列表中的每个项,您将得到一个ContractControl
的空实例
快速而肮脏的解决方案是为中继器的ItemDataBound
事件添加一个处理程序,并将属性复制到实际控件:
protected void myRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
switch (e.Item.ItemType)
{
case ListItemType.Item:
case ListItemType.AlternatingItem:
case ListItemType.SelectedItem:
case ListItemType.EditItem:
{
var source = (ContractControl)e.Item.DataItem;
var destination = (ContractControl)e.Item.FindControl("contractControl");
destination.ContractID = source.ContractID;
destination.TileControl = source.TileControl;
destination.DetailControl = source.DetailControl;
break;
}
}
}
更好的解决方案是将您的中继器
绑定到TFSContract
对象列表,并将代码移动到ContractControl
事件处理程序中以构建ItemDataBound
事件处理程序
编辑
更新为仅处理真实项目,忽略页眉、页脚等。您在base.CreateChildControls()中做什么;?在哪里创建tileControl和detailControl?不管基本方法在做什么。tileControl和detailControl在第页上创建