2011-02-07 16 views
0

単純なASPXページを作成し、ページにListViewコントロールを追加し、ITemplateの2つの実装を作成しました。 1つはLayoutTemplate用、もう1つはItemTemplate用です。ここでのトリックは、ListViewに表示する列のコレクションを指定し、そのコレクションをLayoutTemplateクラスのパラメーターとして指定することです。ここでは、全体のコードです(コールは、「Columns.Skipは、(1)」「LoadDataSource」で、私は列の任意の数とリストビューをレンダリングできるかどうかを確認することだけです):ID「itemPlaceholder」はカスタムLayoutTemplateを使用してレンダリングされません

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(); 
     } 
    } 
} 

私は全く問題視していません列の数を変更することが、私は、ヘッダー内のリンクをクリックしたときに、私が代わりにMethodNotImplementedのこのサーバーエラーを取得してリストビュー:アイテムのプレースホルダは、ListViewの「MyListViewを」上で指定する必要があります

を...

私は答えがひどいと思うightforwardしかし私はちょうどこれの原因を見つけることができません。誰にも何か提案はありますか?これはなぜ起こったか

+0

ただし、LayoutTemplateをプログラムで作成せずに、代わりにLayoutTemplateをマークアップファイルに宣言すると、すべて正常に動作します。 –

答えて

0

さて、私が見つけた - コードは、私がコントロールをロードし、それらに値を割り当てるためにFindControlを使用していMyItemTemplate-> MyTableRow_DataBindingに、すべての

まず...の下に追加されます。これらのコントロールはInstantiateInメソッドで既に追加されています。明らかに、それは正しい方法ではありません。

DataBindingイベントでコントロールを作成し、正しい値を割り当てて、それらをMyHtmlTableRow(送信者パラメータ)に追加する必要があります。

は第二に、私は(thead要素とTBODYを含む)、より複雑なテーブルデザインをレンダリングできるようにするために必要なので、私はHTMLテーブル、HtmlTableRowの使用を交換しHtmlGenericControlと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以外のサーバーコントロールを使用することができます。テーブル、TableHeaderRow、TableHeaderCellなど、それはおそらくこの場合は何の違いもしなかったが、主な問題が解決されたと言うことです。

関連する問題