2008-09-18 8 views
9

Je suis en train d'écrire un contrôle Composite, qui contient un listview pour afficher une table d'éléments. Normalement, en utilisant un ListView dans Asp.NET, je définirais les templates dans le code-forward.Comment définir les modèles listview dans le code

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

Je suppose que c'est quelque chose comme:

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

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

Mise à jour: J'ai créé 2 modèles en implémentant l'interface 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); 
    } 
} 

et je peux les ajouter à l'aide:

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

Mais alors je suis bloqué, puisque container.DataItem est nul.

Répondre

9

L'astuce est de souscrire à l'événement DataBinding du itemplaceholder dans le ItemTemplate.

La solution complète:

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

Ce lien pourrait-il vous être utile? Using Templated Controls Programmatically

La génération des modèles au moment du design (afin de les conserver dans le fichier aspx) est un peu plus complexe, mais DataBinding fonctionnera automatiquement.

+0

Cela ressemble à cela. –

+0

Il renvoie l'erreur 404. –

-1

Configuration d'une classe comme:

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

Et puis procédez comme suit:

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

exemple du bâtiment sur Sonteks est un exemple ici qui crée un modèle qui contient des éléments qui sont ensuite liés en utilisant la liaison de données.

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 

} 
Questions connexes