2010-03-08 12 views
1

Le lien ci-dessous montre un contrôle composite listview dans sa forme la plus basique mais je ne peux pas sembler l'étendre à ce que j'essaie de faire.Conversion de listview en contrôle composite

How to define listview templates in code

Mon listview a 1 tablerow avec 2 champs. Le premier champ contient 1 élément tandis que le second champ contient 2 éléments comme indiqué ci-dessous.

<asp:ListView ID="lstArticle" runat="server"> 
    <LayoutTemplate> 
      <table id="itemPlaceholder" runat="server"> 

      </table> 
    </LayoutTemplate> 
    <ItemTemplate> 
    <div class="ctrlArticleList_rptStandardItem"> 
     <table width="100%"> 
      <tr> 
       <td valign="top" class="ctrlArticleList_firstColumnWidth"> 
        <a href="<%# GetURL(Container.DataItem) %>"> 
         <%# GetImage(Container.DataItem)%> 
        </a> 
       </td> 
       <td valign="top"> 
        <span class="ctrlArticleList_title"> 
         <a href="<%# GetURL(Container.DataItem) %>"> 
          <%# DataBinder.Eval(Container.DataItem, "Title") %> 
         </a> 
        </span>        
        <span class="ctrlArticleList_date"> 
         <%# convertToShortDate(DataBinder.Eval(Container.DataItem, "ActiveDate"))%> 
        </span>         
        <div class="ctrlArticleList_standFirst"> 
         <%# DataBinder.Eval(Container.DataItem, "StandFirst")%> 
        </div> 
       </td> 
      </tr> 
     </table> 
    </div> 
    </ItemTemplate> 

Donc, pour convertir ce que je dois utiliser la méthode InstantiateIn du ITemplate pour la LayoutTemplate et ItemTemplate. Les données sont liées au modèle d'élément à l'aide de l'événement DataBinding.

Ma question pour le moment est de savoir comment configurer la classe ItemTemplate et lier les valeurs à partir du ListView ItemView ci-dessus. Voilà ce que je suis parvenu à ce jour:

private class LayoutTemplate : ITemplate 
    { 
     public void InstantiateIn(Control container) 
     { 
      var table = new HtmlGenericControl("table") { ID = "itemPlaceholder" }; 
      container.Controls.Add(table); 
     } 
    } 

    private class ItemTemplate : ITemplate 
    { 
     public void InstantiateIn(Control container) 
     { 
      var tableRow = new HtmlGenericControl("tr"); 

      //first field in row 
      var tableFieldImage = new HtmlGenericControl("td"); 
      var imageLink = new HtmlGenericControl("a"); 
      imageLink.ID = "imageLink"; 
      tableRow.Controls.Add(imageLink); 

      // second field in row 
      var tableFieldTitle = new HtmlGenericControl("td"); 
      var title = new HtmlGenericControl("a"); 
      tableFieldTitle.Controls.Add(title); 
      tableRow.Controls.Add(tableFieldTitle); 

      //Bind the data with the controls 
      tableRow.DataBinding += BindData; 

      //add the controls to the container 
      container.Controls.Add(tableRow); 
     } 

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

      container.Controls.Add(new Literal() { Text = dataItem.ToString() }); 
     } 

L'une des fonctions dans le code derrière utilisé dans le ListView juste pour un exemple:

 public string GetURL(object objArticle) 
    { 
     ArticleItem articleItem = (ArticleItem)objArticle; 

     Article article = new Article(Guid.Empty, articleItem.ContentVersionID); 

     return GetArticleURL(article); 
    } 

Résumé

Qu'est-ce que dois-je faire pour convertir le suivant en un contrôle composite:

GetURL (Container.DataItem) Ge TImage (Container.DataItem)

GetURL (Container.DataItem) DataBinder.Eval (Container.DataItem "Titre",)

convertToShortDate (DataBinder.Eval (Container.DataItem, "ActiveDate"))

DataBinder.Eval (Container.DataItem, "StandFirst")

Répondre

0

Dans votre contrôle, vous n'avez pas besoin de générer la liaison <% #; plutôt, vous pouvez simplement obtenir l'URL lié sur le serveur et l'attribuer à un lien, créer un lien hypertexte et faire:

var link = new HyperLink(); 
link.NavigateUrl = GetUrl(dataItem); 
link.ImageUrl = GetImage(dataItem); 

Lorsque le DataItem est l'élément de données pour la ligne spécifique, que vous obtenez dans l'élément modèle méthode binddata, non?

Suis-je hors de la base?

HTH.

+0

Merci pour la réponse, je ne sais pas ce que vous voulez dire "Où l'élément de données est l'élément de données pour la ligne spécifique, que vous obtenez dans la méthode binddata de modèle d'objet" – Paul

+0

BindData a ceci: var container = (HtmlGenericControl) expéditeur ; var dataItem = ((ListViewDataItem) conteneur.NamingContainer) .DataItem; Où dataitem est la source de données sous-jacente. l'élément de données serait votre objet de données de sous-évaluation. Si vous rencontrez des difficultés pour extraire des champs, vous pouvez utiliser DataBinder.Eval ou DataBinder.GetPropertyValue pour extraire la valeur de l'objet de manière générique. –

+0

Je suis perdu :) 1. Suis-je sur la bonne voie avec la classe ItemTemplate? - Depuis, j'ai créé les éléments table/row/td/spans/divs et leurs attributs correspondants, maintenant il devrait refléter la page de design. 2.Est-ce que j'utilise le contrôle du serveur au lieu du contrôle html (par exemple HyperLink au lieu de ) 3.Dois-je lier les données aux mêmes points que sur la page de conception. Il y a donc 6 fois quand j'ai besoin de lier les données. 4.Dans le code de conception, 2 types de liaison de données sont utilisés. Le premier passe un objet de données à une fonction et le second le nom de champ de l'objet de données. Comment cela se passe-t-il dans la classe ITemplate? – Paul