C#.net 中的动态中继器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/717539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamic Repeater in C#.net
提问by Mohit
I am trying to create nested repeaters dynamically using ITemplate. This repeater is like that I am passing List<Control>
and it generates repeater. Issue is that when I databound outer repeater. Only the last nested repeater shows. Following is screen shot.
我正在尝试使用 ITemplate 动态创建嵌套转发器。这个中继器就像我路过的那样List<Control>
,它生成中继器。问题是当我数据绑定外部中继器时。仅显示最后一个嵌套的中继器。以下是屏幕截图。
Markup
标记
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Restricted_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table style="border:solid 1px black;">
<tr>
<td>
<asp:PlaceHolder ID="phControls" runat="server" />
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
Code Behind
背后的代码
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
public partial class Restricted_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
CreateNestedRepeater();
}
private void CreateNestedRepeater()
{
Repeater childRpt = new Repeater();
List repeatingRuleControls = new List();
repeatingRuleControls.Add(new TextBox());
repeatingRuleControls.Add(new TextBox());
repeatingRuleControls.Add(new TextBox());
RepeatingRuleTemplate repeatingRuleTemplate = new RepeatingRuleTemplate(ListItemType.Item, repeatingRuleControls);
childRpt.HeaderTemplate = new RepeatingRuleTemplate(ListItemType.Header, repeatingRuleControls);
childRpt.ItemTemplate = repeatingRuleTemplate;
childRpt.FooterTemplate = new RepeatingRuleTemplate(ListItemType.Footer, null);
childRpt.DataSource = new DataRow[4];
Repeater parentRpt = new Repeater();
repeatingRuleControls = new List();
repeatingRuleControls.Add(new TextBox());
repeatingRuleControls.Add(new TextBox());
repeatingRuleControls.Add(new TextBox());
repeatingRuleControls.Add(childRpt);
RepeatingRuleTemplate parentrepeatingRuleTemplate = new RepeatingRuleTemplate(ListItemType.Item, repeatingRuleControls);
parentRpt.HeaderTemplate = new RepeatingRuleTemplate(ListItemType.Header, repeatingRuleControls);
parentRpt.ItemTemplate = parentrepeatingRuleTemplate;
parentRpt.FooterTemplate = new RepeatingRuleTemplate(ListItemType.Footer, null);
parentRpt.DataSource = new DataRow[4];
parentRpt.DataBind();
phControls.Controls.Add(parentRpt);
}
public class RepeatingRuleTemplate : ITemplate
{
ListItemType templateType;
List innerControls;
public RepeatingRuleTemplate(ListItemType type, List controls)
{
templateType = type;
innerControls = controls;
}
public void InstantiateIn(Control container)
{
PlaceHolder ph = new PlaceHolder();
switch (templateType)
{
case ListItemType.Header:
ph.Controls.Add(new LiteralControl(""));
ph.Controls.Add(new LiteralControl(""));
foreach (Control control in innerControls)
{
Label label = new Label();
label.Text = control.ID;
ph.Controls.Add(new LiteralControl(""));
ph.Controls.Add(label);
ph.Controls.Add(new LiteralControl(""));
}
ph.Controls.Add(new LiteralControl(""));
break;
case ListItemType.Item:
ph.Controls.Add(new LiteralControl(""));
foreach (Control control in innerControls)
{
if (control.GetType() != typeof(Repeater))
{
ph.Controls.Add(new LiteralControl(""));
TextBox textBox = new TextBox();
textBox.ID = control.ID;
ph.Controls.Add(textBox);
ph.Controls.Add(new LiteralControl(""));
}
else
{
ph.Controls.Add(new LiteralControl(""));
ph.Controls.Add(control as Repeater);
//(control as Repeater).DataSource = new DataRow[4];
// (control as Repeater).DataBind();
ph.Controls.Add(new LiteralControl(""));
}
}
ph.Controls.Add(new LiteralControl(""));
//ph.DataBinding += new EventHandler(Item_DataBinding);
break;
case ListItemType.Footer:
ph.Controls.Add(new LiteralControl(""));
break;
}
container.Controls.Add(ph);
}
public List Controls
{
get
{
return innerControls;
}
}
}
}
采纳答案by Mohit
Ok guys I figured it out .... Thanks to everyone though. I was doing a mistake. The template class was wrong.I fixed it and now it is working like Charm Follwoing is the class
好吧伙计们,我想通了....谢谢大家。我做错了。模板类是错误的。我修复了它,现在它可以像 Charm Follwoing 一样工作
public class RepeatingRuleTemplate : ITemplate
{
ListItemType templateType;
List innerControls;
public RepeatingRuleTemplate(ListItemType type, List<Control> controls)
{
templateType = type;
innerControls = controls;
}
public void InstantiateIn(Control container)
{
PlaceHolder ph = new PlaceHolder();
switch (templateType)
{
case ListItemType.Header:
ph.Controls.Add(new LiteralControl("<table border=\"0\">"));
ph.Controls.Add(new LiteralControl("<tr>"));
foreach (Control control in innerControls)
{
Label label = new Label();
label.Text = control.ID;
ph.Controls.Add(new LiteralControl("<td>"));
ph.Controls.Add(label);
ph.Controls.Add(new LiteralControl("</td>"));
}
ph.Controls.Add(new LiteralControl("</tr>"));
break;
case ListItemType.Item:
ph.Controls.Add(new LiteralControl("<tr>"));
foreach (Control control in innerControls)
{
//ph.Controls.Add(new LiteralControl("<td>"));
//ph.Controls.Add(control as TextBox);
//ph.Controls.Add(new LiteralControl("</td>"));
if (control.GetType() != typeof(Repeater))
{
ph.Controls.Add(new LiteralControl("<td>"));
TextBox textBox = new TextBox();
textBox.ID = control.ID;
ph.Controls.Add(textBox);
ph.Controls.Add(new LiteralControl("</td>"));
}
else
{
ph.Controls.Add(new LiteralControl("<td>"));
Repeater rpt = new Repeater();
rpt.DataSource = (control as Repeater).DataSource;
rpt.ItemTemplate = (control as Repeater).ItemTemplate;
rpt.HeaderTemplate = (control as Repeater).HeaderTemplate;
rpt.FooterTemplate = (control as Repeater).FooterTemplate;
rpt.DataBind();
ph.Controls.Add(rpt);
//(control as Repeater).DataSource = new DataRow[4];
// (control as Repeater).DataBind();
ph.Controls.Add(new LiteralControl("</td>"));
}
}
ph.Controls.Add(new LiteralControl("</tr>"));
//ph.DataBinding += new EventHandler(Item_DataBinding);
break;
case ListItemType.Footer:
ph.Controls.Add(new LiteralControl("</table>"));
break;
}
container.Controls.Add(ph);
}
public List<Control> Controls
{
get
{
return innerControls;
}
}
}
回答by radimd
You need to write handler for parentRpt.ItemDataBound event and set DataSource property of childRpt and then call child.Rpt.DataBind() from there.
您需要为 parentRpt.ItemDataBound 事件编写处理程序并设置 childRpt 的 DataSource 属性,然后从那里调用 child.Rpt.DataBind()。
回答by Mike Chaliy
Why not just to make build custom control and fill it with your code?
为什么不只是构建自定义控件并用您的代码填充它?
override CreateChildControls(){
foreach(var r in rows)
{
...
}
}
Templates, repreaters and so on are just to make design expirience better, in your situation when you build all manually I cannot see a reason why overcomplicate with all that placeholder, templates and so on...
模板、repeaters 等只是为了让设计体验更好,在你手动构建的情况下,我看不出为什么所有这些占位符、模板等过于复杂的原因......
Just build CompositeControl and fill it with your code. You will reduce your code twice and what is the best you will have readable code. Witout nasty events to wire child repreaters DataSource properties.
只需构建 CompositeControl 并用您的代码填充它。您将减少两次代码,什么是最好的可读代码。没有讨厌的事件来连接子节点的数据源属性。
Sorry for hard offtop...
对不起,硬断层...