Идентификатор "itemPlaceholder" не отображается при использовании пользовательского LayoutTemplate - PullRequest
0 голосов
/ 07 февраля 2011

Я создал простую ASPX-страницу, добавил элемент управления ListView на страницу и создал две реализации ITemplate;один для LayoutTemplate и один для ItemTemplate.Хитрость заключается в том, что я указываю коллекцию столбцов, которую я хочу отобразить в ListView, и предоставляю коллекцию в качестве параметра моему классу LayoutTemplate.Вот весь код (вызов «Columns.Skip (1)» в «LoadDataSource» просто для проверки того, что я могу визуализировать 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' должен быть указан заполнитель элемента.

Я думаю, что ответ прост, но я просто не могу найти причину этого.У кого-нибудь есть предложения?

1 Ответ

0 голосов
/ 08 февраля 2011

Хорошо, я узнал, почему это произошло - код добавлен ниже ...

Прежде всего, в MyItemTemplate-> MyTableRow_DataBinding я использую FindControl для загрузки элементов управления и присвоения им значений. Эти элементы управления уже были добавлены в метод InstantiateIn. Видимо, это не правильный путь.

Вместо этого вам нужно создать элементы управления в событии DataBinding, назначить правильные значения и добавить их в MyHtmlTableRow (параметр отправителя).

Во-вторых, мне нужно было иметь возможность визуализировать более сложный дизайн таблицы (включая thead и tbody), поэтому я заменил использование HtmlTable, HtmlTableRow и HtmlTableCell на HtmlGenericControl и передал имя тега в качестве параметра, например так:

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 и т. Д., Т. Е. В этом случае, вероятно, ничего не изменилось, но основная проблема решена.

...