我正在编写一个Composite控件,它包含一个listview来显示一个项目表.通常在Asp.NET中使用ListView时,我会在代码转发中定义模板.
<asp:ListView runat="server" ID="ArticleList"> <LayoutTemplate> <div class="ContentContainer"> <div runat="server" id="itemPlaceholder" /> </div> </LayoutTemplate> <ItemTemplate> <div> <div><%# Eval("Content") %></div> </div> </ItemTemplate> </asp:ListView>
我假设它是这样的:
ListView view = new ListView(); view.LayoutTemplate = ..... view.ItemTemplate = ..... // when do I call these? view.DataSource = myDataSource; view.DataBind();
更新:
我通过实现ITemplate接口创建了2个模板:
private class LayoutTemplate : ITemplate { public void InstantiateIn(Control container) { var outer = new HtmlGenericControl("div"); var inner = new HtmlGenericControl("div") { ID = "itemPlaceholder" }; table.Rows.Add(row); container.Controls.Add(table); } } private class ItemTemplate : ITemplate { public void InstantiateIn(Control container) { var inner = new HtmlGenericControl("div"); container.Controls.Add(inner); } }
dataList.LayoutTemplate = new LayoutTemplate(); dataList.ItemTemplate = new ItemTemplate();
但后来我卡住了,因为container.DataItem为null.
解决方法
诀窍是订阅ItemTemplate中itemplaceholder的数据绑定事件.
完整的解决方案:
public class FibonacciControl : CompositeControl { public FibonacciControl() { // .... } protected override void CreateChildControls() { base.CreateChildControls(); ListView view = new ListView(); view.LayoutTemplate = new LayoutTemplate(); view.ItemTemplate = new ItemTemplate(); view.DataSource = FibonacciSequence(); view.DataBind(); this.Controls.Add(view); } private IEnumerable<int> FibonacciSequence() { int i1 = 0; int i2 = 1; for (int i = 0; i < Iterations; i++) { yield return i1 + i2; int temp = i1 + i2; i1 = i2; i2 = temp; } yield break; } public int Iterations { get; set; } private class LayoutTemplate : ITemplate { public void InstantiateIn(Control container) { var ol = new HtmlGenericControl("ol"); var li = new HtmlGenericControl("li") { ID = "itemPlaceholder" }; ol.Controls.Add(li); container.Controls.Add(ol); } } private class ItemTemplate : ITemplate { public void InstantiateIn(Control container) { var li = new HtmlGenericControl("li"); li.DataBinding += DataBinding; container.Controls.Add(li); } public void DataBinding(object sender,EventArgs e) { var container = (HtmlGenericControl)sender; var dataItem = ((ListViewDataItem)container.NamingContainer).DataItem; container.Controls.Add( new Literal(){Text = dataItem.ToString() }); } } }