2008-09-18 12 views
9

Estoy escribiendo un control compuesto, que contiene una vista de lista para mostrar una tabla de elementos. Normalmente, al usar un ListView en Asp.NET, definiría las plantillas en el código de avance.Cómo definir plantillas de vista de lista en el código

<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> 

supongo que es algo así como:

ListView view = new ListView(); 
view.LayoutTemplate = ..... 
view.ItemTemplate = ..... 

// when do I call these? 
view.DataSource = myDataSource; 
view.DataBind(); 

Actualización: he creado 2 plantillas implementando la interfaz ITemplate:

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

y puedo añadirlos usando:

dataList.LayoutTemplate = new LayoutTemplate(); 
dataList.ItemTemplate = new ItemTemplate(); 

Pero luego me quedo atascado, ya que container.DataItem es nulo.

Respuesta

9

El truco es para suscribirse al evento de enlace de datos de la itemplaceholder en el ItemTemplate.

La solución completa:

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

¿Podría ser de ayuda este enlace? Using Templated Controls Programmatically

Generar las plantillas en tiempo de diseño (para persistirlas en el archivo aspx) es un poco más complicado, pero el enlace de datos funcionará automáticamente.

+0

Parece que podría. –

+0

Devuelve el error 404. –

-1

instalación de una clase como:

public delegate void InstantiateTemplateDelegate(Control container); 

public class GenericTemplateImplementation : ITemplate 
{ 
    private InstantiateTemplateDelegate instantiateTemplate; 

    public void InstantiateIn(Control container) 
    { 
     this.instantiateTemplate(container); 
    } 

    public GenericTemplateImplementation(InstantiateTemplateDelegate instantiateTemplate) 
    { 
     this.instantiateTemplate = instantiateTemplate; 
    } 
} 

Y a continuación, haga lo siguiente:

view.LayoutTemplate = new GenericTemplateImplementation(p => 
       { 
        p.Controls.Add(new Label { Text = "Foo" }); 
       }); 
0

Basándose en Sonteks ejemplo es un ejemplo que crea una plantilla que contiene elementos que a continuación se enlazan con el enlace de datos.

public partial class View : PortalModuleBase 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 

    } 

    #region MasterListView_ItemDataBound 
    public void MasterListView_ItemDataBound(object sender, ListViewItemEventArgs e) 
    { 
     ListViewItem objListViewItem = (ListViewItem)e.Item; 
     ListViewDataItem objListViewDataItem = objListViewItem as ListViewDataItem; 

     if (objListViewDataItem != null) 
     { 
      Tab objTab = (Tab)objListViewDataItem.DataItem; 
      IEnumerable<Tab> Tabs = CustomData(objTab.TabID); 

      Label TabIDLabel = (Label)objListViewItem.FindControl("TabIDLabel"); 
      Label TabNameLabel = (Label)objListViewItem.FindControl("TabNameLabel"); 

      TabIDLabel.Text = objTab.TabID.ToString(); 
      TabNameLabel.Text = objTab.TabName; 

      AddListView(objTab.TabName, objListViewItem, Tabs); 
     } 
    } 
    #endregion 

    #region CustomData 
    static IEnumerable<Tab> CustomData(int? ParentID) 
    { 
     TabAdminDataContext objTabAdminDataContext = new TabAdminDataContext(); 

     var myCustomData = from Tabs in objTabAdminDataContext.Tabs 
          where Tabs.ParentId == ParentID 
          select Tabs; 

     return myCustomData.AsEnumerable(); 
    } 
    #endregion 

    #region AddListView 
    private void AddListView(string CurrentTabName, Control container, IEnumerable<Tab> ChildTabs) 
    { 
     // The Tab has Children so add a ListView 
     if (ChildTabs.Count() > 0) 
     { 
      ListView ChildListView = new ListView(); 
      ChildListView.ID = "ChildListView"; 
      ChildListView.ItemCommand += ListView_ItemCommand; 
      ChildListView.EnableViewState = true; 
      ChildListView.LayoutTemplate = new MyLayoutTemplate(); 
      ChildListView.ItemTemplate = new MyItemTemplate(); 
      ChildListView.DataSource = ChildTabs; 
      ChildListView.DataBind(); 

      // Put the ListView in a Panel 
      var oTR = new HtmlGenericControl("tr") { ID = "ChildListViewTR" }; 
      var oTD = new HtmlGenericControl("td") { ID = "ChildListViewTD" }; 

      Panel objPanel = new Panel(); 
      objPanel.ID = "ListViewPanel"; 
      objPanel.ToolTip = CurrentTabName; 
      objPanel.Controls.Add(ChildListView); 

      oTD.Controls.Add(objPanel); 
      oTR.Controls.Add(oTD); 
      container.Controls.Add(oTR); 
     } 
    } 
    #endregion 

    #region ListView_ItemCommand 
    protected void ListView_ItemCommand(object sender, ListViewCommandEventArgs e) 
    { 
     LinkButton objButton = (LinkButton)sender; 
     Label1.Text = objButton.Text; 
     MasterListView.DataBind(); 
    } 
    #endregion 

    #region MyLayoutTemplate 
    public class MyLayoutTemplate : ITemplate 
    { 
     public void InstantiateIn(Control container) 
     { 
      var oTR = new HtmlGenericControl("tr") { ID = "itemPlaceholder" }; 
      container.Controls.Add(oTR); 
     } 
    } 
    #endregion 

    #region ItemTemplate 
    public class MyItemTemplate : ITemplate 
    { 
     public void InstantiateIn(Control container) 
     { 
      var oTR = new HtmlGenericControl("tr"); 

      var oTD1 = new HtmlGenericControl("td"); 
      LinkButton TabIDLinkButton = new LinkButton(); 
      TabIDLinkButton.ID = "TabIDLinkButton"; 
      oTD1.Controls.Add(TabIDLinkButton); 
      oTR.Controls.Add(oTD1); 

      var oTD2 = new HtmlGenericControl("td"); 
      Label TabNameLabel = new Label(); 
      TabNameLabel.ID = "TabNameLabel"; 
      oTD2.Controls.Add(TabNameLabel); 
      oTR.Controls.Add(oTD2); 

      oTR.DataBinding += DataBinding; 
      container.Controls.Add(oTR); 
     } 

     public void DataBinding(object sender, EventArgs e) 
     { 
      var container = (HtmlGenericControl)sender; 
      var dataItem = ((ListViewDataItem)container.NamingContainer).DataItem; 
      Tab objTab = (Tab)dataItem; 

      LinkButton TabIDLinkButton = (LinkButton)container.FindControl("TabIDLinkButton"); 
      Label TabNameLabel = (Label)container.FindControl("TabNameLabel"); 

      TabIDLinkButton.Text = "+" + objTab.TabID.ToString(); 
      TabNameLabel.Text = objTab.TabName; 

      IEnumerable<Tab> ChildTabs = View.CustomData(objTab.TabID); 

      View objView = new View(); 
      objView.AddListView(objTab.TabName, container, ChildTabs); 
     } 

    } 
    #endregion 

} 
Cuestiones relacionadas