I am quite stubborn in keeping .aspx clean, try to keep only asp and html tag in it.
Until recently I need to use ListView and bind my data to it, almost 90% of the example available are using <%# Eval(“[PropertyName]”) %>.
But I really don’t want to stuff my .aspx with these things, I don’t know if they are VBScript or ASP code, anyway, I want to do that in C# code.
I image that is possible to customize my binding just like I did in Java. After searching and reading articles for a few hours, I finally got it.
I want to share my experience here hoping to save someone a few hours. I will try to give sample code download if I can.
First step, drag a ListView control to your page. There are three things a ListView must have.
1.You must have a <LayoutTemplate> in your ListView.
2.You must have a <PlaceHolder> in your <LayoutTemplate>.
3.Set ItemPlaceholderId to your PlaceHolder Id.
I am using table to display my data. You will result in something that looks like this:
<asp:ListView ID="ltv_users" runat="server" ItemPlaceholderID="plh_userItems" onitemcommand="ltv_users_ItemCommand" ondatabinding="ltv_users_DataBinding" onitemdeleting="ltv_users_ItemDeleting"> <LayoutTemplate> <table class="ListViewTableStyle" border="1"> <thead class="ListViewHeaderStyle"> <tr> <td> </td> <td> Column Header 1 </td> <td> Column Header 2 </td> </tr> </thead> <tbody> <asp:PlaceHolder ID="plh_userItems" runat="server"></asp:PlaceHolder> </tbody> </table> </LayoutTemplate> </asp:ListView>
Second Step is to define your own customize Template to do data binding. Create a class which implement ITemplate interface under System.Web.UI namespace. People usually pass an enumerator to the constructor to indicate what type of template to create. The result looks like this.
public class UserTemplate : ITemplate { protected ListViewTemplateType m_templateType; public UserTemplate(ListViewTemplateType type) { m_templateType = type; } }
ListViewTemplateType is just an enumerator one to one maps to template available inside ListView tag. Then we implement two methods, InstantiateIn(Control container) which response for creating html tags and data binding method. Here is an example for generating different tags for different template.
public void InstantiateIn(Control container) { //for itemtemplate and alternativeitemtemplate LinkButton l_btnDetail = new LinkButton() { Text = m_DetailBtnText, ID = "btnDetail", CommandName = "Detail", CssClass = "ListViewButton" }; LinkButton l_btnRole = new LinkButton() { Text = m_RoleBtnText, ID = "btnRole", CommandName = "Role", CssClass = "ListViewButton" }; LinkButton l_btnDelete = new LinkButton() { Text = m_DeleteBtnText, ID = "btnDelete", CommandName = "Delete", CssClass = "ListViewButton" }; Label l_lblAccount = new Label() { ID = "lblAccount" }; Label l_lblUserName = new Label() { ID = "lblUserName" }; switch (m_templateType) { //ListViewItemType. case ListViewTemplateType.ItemTemplate: container.Controls.Add(new LiteralControl("<tr class=\"ListViewItemStyle\"><td>")); container.Controls.Add(l_btnDetail); container.Controls.Add(l_btnRole); container.Controls.Add(l_btnDelete); container.Controls.Add(new LiteralControl("</td><td>")); container.Controls.Add(l_lblAccount); container.Controls.Add(new LiteralControl("</td><td>")); container.Controls.Add(l_lblUserName); container.Controls.Add(new LiteralControl("</td></tr>")); container.DataBinding += new EventHandler(ItemTemplate_DataBinding); break; case ListViewTemplateType.AlternatingItemTemplate: container.Controls.Add(new LiteralControl("<tr class=\"ListViewAlternativeItemStyle\"><td>")); container.Controls.Add(l_btnDetail); container.Controls.Add(l_btnRole); container.Controls.Add(l_btnDelete); container.Controls.Add(new LiteralControl("</td><td>")); container.Controls.Add(l_lblAccount); container.Controls.Add(new LiteralControl("</td><td>")); container.Controls.Add(l_lblUserName); container.Controls.Add(new LiteralControl("</td></tr>")); container.DataBinding += new EventHandler(ItemTemplate_DataBinding); break; } }
We need to define controls id so that we can later bind data to them by their id in ItemTemplate_DataBinding().
public void ItemTemplate_DataBinding(object sender, EventArgs e) { ListViewDataItem listViewDataItem = (ListViewDataItem)sender; string l_account = (string)DataBinder.Eval(listViewDataItem.DataItem, "Account"); string l_userName = (string)DataBinder.Eval(listViewDataItem.DataItem, "FirstName") + (string)DataBinder.Eval(listViewDataItem.DataItem, "LastName"); Guid l_userId = (Guid)DataBinder.Eval(listViewDataItem.DataItem, "Id"); switch (m_templateType) { case ListViewTemplateType.ItemTemplate: case ListViewTemplateType.AlternatingItemTemplate: ((LinkButton)listViewDataItem.FindControl("btnDetail")).CommandArgument = l_userId.ToString(); ((LinkButton)listViewDataItem.FindControl("btnRole")).CommandArgument = l_userId.ToString(); //((LinkButton)listViewDataItem.FindControl("btnDelete")).CommandArgument = l_userId.ToString(); LinkButton btnDelete = (LinkButton)listViewDataItem.FindControl("btnDelete"); btnDelete.CommandArgument = l_userId.ToString(); btnDelete.OnClientClick = m_ConfirmScript; ((Label)listViewDataItem.FindControl("lblAccount")).Text = l_account; ((Label)listViewDataItem.FindControl("lblUserName")).Text = l_userName; break; } }
I am using a fall through here because ItemTemplate and AlternatingItemTemplate are binding data in the same way. You can bind textbox for ItemEditTemplate. I am going to show how to use this template class we make just now. How to work under asp page life cycle and use your own data source, and something about default ListView event handling. Read It Now!