我创建了一个简单的ASPX页面,向页面添加了ListView控件并创建了两个ITemplate实现;一个用于LayoutTemplate,另一个用于ItemTemplate。这里的技巧是我指定要在ListView中显示的列集合,并将集合作为参数提供给我的LayoutTemplate类。这是整个代码(“LoadDataSource”中对“Columns.Skip(1)”的调用仅仅是为了验证我可以使用任意数量的列渲染ListView):
public partial class ListViewITemplate : System.Web.UI.Page
{
private static IList<string> Columns
{
get
{
return new List<string>() { "ColumnA", "ColumnB", "ColumnC", "ColumnD", "ColumnE" };
}
}
protected void Page_Load(object sender, EventArgs e)
{
DataTable dataTable = LoadDataSource();
IEnumerable<string> columns = dataTable.Columns.Cast<DataColumn>().Select(column => column.ColumnName);
MyListView.LayoutTemplate = new MyLayoutTemplate(columns);
MyListView.ItemTemplate = new MyItemTemplate(columns);
MyListView.DataSource = dataTable;
MyListView.DataBind();
}
private static DataTable LoadDataSource()
{
DataTable dataTable = new DataTable();
IEnumerable<string> selectedColumns = Columns.Skip(1);
foreach (string column in selectedColumns)
{
dataTable.Columns.Add(column, typeof(string));
}
for (int i = 0; i < 100; i++)
{
DataRow dataRow = dataTable.NewRow();
foreach (string column in selectedColumns)
{
dataRow[column] = "Data in " + column + " " + i;
}
dataTable.Rows.Add(dataRow);
}
return dataTable;
}
}
public class MyLayoutTemplate : ITemplate
{
private IEnumerable<string> Columns { get; set; }
public MyLayoutTemplate(IEnumerable<string> columns)
{
Columns = columns;
}
public void InstantiateIn(Control container)
{
HtmlTable MyHtmlTable = new HtmlTable();
HtmlTableRow MyHtmlTableRow = new HtmlTableRow();
MyHtmlTableRow.Attributes["class"] = "tableheader";
foreach (string column in Columns)
{
HtmlTableCell MyHtmlTableCell = new HtmlTableCell();
LinkButton MyLinkButton = new LinkButton();
MyLinkButton.ID = "lbn" + column;
MyLinkButton.Text = column;
MyLinkButton.ToolTip = "Sort by " + column;
MyLinkButton.CommandArgument = column;
MyLinkButton.Command += new CommandEventHandler(MyLinkButton_Command);
MyHtmlTableCell.Controls.Add(MyLinkButton);
MyHtmlTableRow.Cells.Add(MyHtmlTableCell);
}
MyHtmlTable.Rows.Add(MyHtmlTableRow);
HtmlTableRow htmlTableRow = new HtmlTableRow();
htmlTableRow.ID = "itemPlaceholder";
MyHtmlTable.Rows.Add(htmlTableRow);
container.Controls.Add(MyHtmlTable);
}
void MyLinkButton_Command(object sender, CommandEventArgs e)
{
throw new NotImplementedException();
}
}
public class MyItemTemplate : ITemplate
{
private IEnumerable<string> Columns { get; set; }
public MyItemTemplate(IEnumerable<string> columns)
{
Columns = columns;
}
public void InstantiateIn(Control container)
{
HtmlTableRow MyHtmlTableRow = new HtmlTableRow();
foreach (string column in Columns)
{
HtmlTableCell MyHtmlTableCell = new HtmlTableCell();
MyHtmlTableCell.ID = "MyHtmlTableCell" + column;
Literal MyLiteral = new Literal();
MyLiteral.ID = "Data" + column;
MyHtmlTableCell.Controls.Add(MyLiteral);
MyHtmlTableRow.Cells.Add(MyHtmlTableCell);
}
MyHtmlTableRow.DataBinding += new EventHandler(MyTableRow_DataBinding);
container.Controls.Add(MyHtmlTableRow);
}
protected void MyTableRow_DataBinding(object sender, EventArgs e)
{
HtmlTableRow MyHtmlTableRow = (HtmlTableRow)sender;
DataRowView dataRowView = ((ListViewDataItem)MyHtmlTableRow.NamingContainer).DataItem as DataRowView;
foreach (string column in Columns)
{
HtmlTableCell MyHtmlTableCell = (HtmlTableCell)MyHtmlTableRow.FindControl("MyHtmlTableCell" + column);
Literal MyLiteral = (Literal)MyHtmlTableCell.FindControl("Data" + column);
MyLiteral.Text = dataRowView[column].ToString();
}
}
}
使用不同数量的列查看ListView没有问题,但每当我单击标题中的链接时,我都会收到此服务器错误,而不是MethodNotImplemented:
必须在ListView“MyListView”上指定项目占位符...
我认为答案很简单,但我找不到原因。有没有人有任何建议?
答案 0 :(得分:0)
好的,我发现了为什么会这样 - 代码添加在下面......
首先,在MyItemTemplate-&gt; MyTableRow_DataBinding中我使用FindControl加载控件并为它们赋值。这些控件已添加到InstantiateIn方法中。显然,这不是正确的方式。
相反,您需要在DataBinding事件中创建控件,分配正确的值并将它们添加到MyHtmlTableRow(sender参数)。
其次,我需要能够呈现更复杂的表设计(包括thead和tbody),所以我用HtmlGenericControl替换了HtmlTable,HtmlTableRow和HtmlTableCell的使用,并将标记名称作为参数传递,如下所示:
public partial class ListViewITemplate : System.Web.UI.Page
{
private static IList<string> Columns
{
get
{
return new List<string>() { "ColumnA", "ColumnB", "ColumnC", "ColumnD", "ColumnE" };
}
}
protected void Page_Load(object sender, EventArgs e)
{
DataTable dataTable = LoadDataSource();
IEnumerable<string> columns = dataTable.Columns.Cast<DataColumn>().Select(column => column.ColumnName);
MyListView.LayoutTemplate = new MyLayoutTemplate(columns);
MyListView.ItemTemplate = new MyItemTemplate(columns);
MyListView.DataSource = dataTable;
MyListView.DataBind();
}
private static DataTable LoadDataSource()
{
DataTable dataTable = new DataTable();
IEnumerable<string> selectedColumns = Columns.Skip(1);
foreach (string column in selectedColumns)
{
dataTable.Columns.Add(column, typeof(string));
}
for (int i = 0; i < 100; i++)
{
DataRow dataRow = dataTable.NewRow();
foreach (string column in selectedColumns)
{
dataRow[column] = "Data in " + column + " " + i;
}
dataTable.Rows.Add(dataRow);
}
return dataTable;
}
}
public class MyLayoutTemplate : ITemplate
{
private IEnumerable<string> Columns { get; set; }
public MyLayoutTemplate(IEnumerable<string> columns)
{
Columns = columns;
}
public void InstantiateIn(Control container)
{
HtmlGenericControl MyHtmlTable = new HtmlGenericControl("table");
HtmlGenericControl MyHtmlTableHead = new HtmlGenericControl("thead");
HtmlGenericControl MyHtmlTableRow = new HtmlGenericControl("tr");
foreach (string column in Columns)
{
HtmlGenericControl MyHtmlTableCell = new HtmlGenericControl("th");
LinkButton MyLinkButton = new LinkButton();
MyLinkButton.ID = "lbn" + column;
MyLinkButton.Text = column;
MyLinkButton.ToolTip = "Sort by " + column;
MyLinkButton.CommandArgument = column;
MyLinkButton.Command += new CommandEventHandler(MyLinkButton_Command);
MyHtmlTableCell.Controls.Add(MyLinkButton);
MyHtmlTableRow.Controls.Add(MyHtmlTableCell);
}
MyHtmlTableHead.Controls.Add(MyHtmlTableRow);
MyHtmlTable.Controls.Add(MyHtmlTableHead);
HtmlGenericControl MyHtmlTableBody = new HtmlGenericControl("tbody");
HtmlGenericControl MyHtmlItemPlaceholderRow = new HtmlGenericControl("tr");
MyHtmlItemPlaceholderRow.ID = "itemPlaceholder";
MyHtmlTableBody.Controls.Add(MyHtmlItemPlaceholderRow);
MyHtmlTable.Controls.Add(MyHtmlTableBody);
container.Controls.Add(MyHtmlTable);
}
protected void MyLinkButton_Command(object sender, CommandEventArgs e)
{
throw new NotImplementedException();
}
}
public class MyItemTemplate : ITemplate
{
private IEnumerable<string> Columns { get; set; }
public MyItemTemplate(IEnumerable<string> columns)
{
Columns = columns;
}
public void InstantiateIn(Control container)
{
HtmlGenericControl MyHtmlTableRow = new HtmlGenericControl("tr");
MyHtmlTableRow.DataBinding += new EventHandler(MyTableRow_DataBinding);
container.Controls.Add(MyHtmlTableRow);
}
protected void MyTableRow_DataBinding(object sender, EventArgs e)
{
HtmlGenericControl MyHtmlTableRow = (HtmlGenericControl)sender;
DataRowView dataRowView = ((ListViewDataItem)MyHtmlTableRow.NamingContainer).DataItem as DataRowView;
foreach (string column in Columns)
{
HtmlGenericControl MyHtmlTableCell = new HtmlGenericControl("td");
MyHtmlTableCell.ID = "MyHtmlTableCell" + column;
Literal MyLiteral = new Literal();
MyLiteral.ID = "Data" + column;
MyLiteral.Text = dataRowView[column].ToString();
MyHtmlTableCell.Controls.Add(MyLiteral);
MyHtmlTableRow.Controls.Add(MyHtmlTableCell);
}
}
}
作为一个注释,您可以使用除HtmlGenericControl之外的其他服务器控件,例如: Table,TableHeaderRow,TableHeaderCell等,也就是说它在这种情况下可能没有任何区别,但主要问题已经解决。