Question

The link below shows a listview composite control in its most basic form however I can't seem to extend this to what I'm trying to do.

How to define listview templates in code

My listview has 1 tablerow with 2 fields. The first field contains 1 element whilst the second field contains 2 elements as shown below.

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

So to convert this I have to use the InstantiateIn method of the ITemplate for the layouttemplate and the ItemTemplate. Data is bound to the itemtemplate using the DataBinding event.

My question at the moment is how do I setup the ItemTemplate class and bind the values from the above ListView ItemTemplate. This is what I've managed so far:

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

One of the functions in the code behind used in the ListView just for an example is:

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

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

        return GetArticleURL(article);
    }

Summary

What do I need to do to convert the following into a composite control:

GetURL(Container.DataItem) GetImage(Container.DataItem)

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

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

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

Was it helpful?

Solution

In your control, you don't need to generate the <%# binding; rather, you can just get the bound URL on the server and assign it to a link, create a HyperLink and do:

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

Where the dataItem is the data item for the specific row, which you get within the item template binddata method, right?

Am I off base?

HTH.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top