玩轉ListView

前陣子,應邀到某企業講述ASP.NET 3.5的新功能,我於課堂中展示了一個應用ListView控件的例子

 

玩轉ListView
 
/黃忠成
 
 
 前陣子,應邀到某企業講述ASP.NET 3.5的新功能,我於課堂中展示了一個應用ListView控件的例子,當學員看到此範例時,脫口而出一句【好漂亮】,讓我覺得此例應該放到Blog上跟大家分享。
 這個例子事實上已寫好許久,在ASP.NET 3.5剛推出時,我對ListView控件充滿好奇,就ASP.NET 2.0所提供的資料控件,複雜易用的有GridView、FormView,簡單具延展性的有Repeater、DataList,那ListView又該放在那個位置呢?就ListView控件的功能來論,其具備了GridView、FormView複雜易用的特色,同時也具備了Repeater、DataList的延展性,下表是這些控件的比較表。
表1

功能
GridView
FormView
Repeater
DataList
ListView
內建編輯功能
*
*
X
X
*
內建刪除功能
*
*
X
X
*
內建新增功能
*
*
X
X
*
可自訂Container、Header、Item等Template
X
X
*
*
*
支援分頁
*
*
X
X
*
仔細看這張表後,你應該可以了解,ListView控件是一個夾縫中的產物,也可稱為是一個具備延展性的GridView控件。
 那麼問題來了,有那種例子可以充份發揮ListView控件呢?這個例子必須是GridView、DataList等控件難以達成、甚至無法達成的,我腦中一閃而過的是一個很特別的商品展示頁面,以往,在展示商品時,我們都會應用GridView來進行條列式展示,這也是GridView唯一能做的呈現,但現在有ListView,我們可以自定Container、Header、Item等Layout,再用條列式就未免太浪費了。
 因此我嘗試一種新的、但能吸引目光的呈現,那就是環狀展示,也可稱為圓形展示,圖1是此想法的實現圖。
圖1
ListViewDemo
很明顯的,要完成這個例子,我們必須充份的使用網頁中常見的絕對座標來定位每個Item的位置!以ListView控件所開放的Template而言,我們可以將LayoutTemplate設成Panel,然後將每個ItemTemplate也設成Panel,然後將每個ItemTemlate中的Panel控件設成絕對座標制。結果就是下列的程式碼:
程式1

.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <style type="text/css">
        .shadowPanel
        {
            border: thin solid #000000;
        }
        .shadowPanel1
        {
            border-style: none solid solid none;
            border-width: 5px;
            border-color: #C0C0C0;
        }
    </style>
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:SqlDataSource ID="SqlDataSource1" runat="server"
            ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
            SelectCommand="SELECT [BOOK_ID], [NAME], [PIC_URL] FROM [BOOKS]"></asp:SqlDataSource>
        <asp:ListView ID="ListView1" runat="server" DataKeyNames="BOOK_ID"
            DataSourceID="SqlDataSource1" style="top: 48px; left: 10px; right: 772px;"
            onitemdatabound="ListView1_ItemDataBound">
            <LayoutTemplate>
                <asp:Panel ID="itemPlaceholderContainer" runat="server"
                style="position:absolute">
                <div ID="itemPlaceholder" style="" runat="server">
                    </div>
                </asp:Panel>                   
                </LayoutTemplate>
                <ItemTemplate>         
                <asp:Panel ID="container1" CssClass="shadowPanel1" style="height:154px;width:119px" runat=server>
                <asp:Panel ID="itemContainer1" runat="server" Height="150px" Width="113px" CssClass="shadowPanel">                              
                <table>
                <tr>
                <td>
                <asp:Image ID="Img1" ImageUrl='<%# HttpUtility.HtmlEncode((string)Eval("PIC_URL")) %>' Height="148px" Width="108px" ImageAlign="Left" runat="server" />
                </td>
                </tr>
                <tr>
                <td>
                <asp:Label ID="LastNameLabel" runat="server" Text='<%# HttpUtility.HtmlEncode((string)Eval("NAME")) %>' />
                </td>
                </tr>
                </table>
                </asp:Panel>
                </asp:Panel>
                </ItemTemplate>
            </asp:ListView>
        <asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1"
            PageSize="8">
            <Fields>
                <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True"
                    ShowLastPageButton="True" />
            </Fields>
        </asp:DataPager>
    </div>
    </form>
</body>
</html>
.aspx.cs
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;
 
 
public partial class Default2 : System.Web.UI.Page
{
    private int index = 0;
 
    protected void Page_Load(object sender, EventArgs e)
    {
 
    }
 
    private static List<Dictionary<string, string>> _positions =
                new List<Dictionary<string, string>>();
 
    static Default2()
    {
        _positions.Add(new Dictionary<string, string>() {
                {"Top","19px"},
                {"Left","467px"}
                });
        _positions.Add(new Dictionary<string, string>() {
                {"Top","89px"},
                {"Left","321px"}
                });
        _positions.Add(new Dictionary<string, string>() {
                {"Top","201px"},
                {"Left","180px"}
                });
        _positions.Add(new Dictionary<string, string>() {
                {"Top","364px"},
                {"Left","318px"}
                });
        _positions.Add(new Dictionary<string, string>() {
                {"Top","446px"},
                {"Left","480px"}
                });
        _positions.Add(new Dictionary<string, string>() {
                {"Top","361px"},
                {"Left","636px"}
                });
        _positions.Add(new Dictionary<string, string>() {
                {"Top","203px"},
                {"Left","772px"}
                });
        _positions.Add(new Dictionary<string, string>() {
                {"Top","93px"},
                {"Left","634px"}
                });
 
    }
 
    protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
    {
        if (e.Item.ItemType == ListViewItemType.DataItem)
        {
            Panel pnl = (Panel)e.Item.FindControl("container1");
            pnl.Style[HtmlTextWriterStyle.Height] = "154px";
            pnl.Style[HtmlTextWriterStyle.Width] = "117px";
            pnl.Style[HtmlTextWriterStyle.Position] = "absolute";
            pnl.Style[HtmlTextWriterStyle.Top] = _positions[index]["Top"];
            pnl.Style[HtmlTextWriterStyle.Left] = _positions[index]["Left"];
            index++;
        }
    }
}
這個例子中,精華部份是絕對位置的設定及Dictionary的Collection Initializes。當然,這個例子要用Repeater及DataList來呈現也不是不可能,但是若真的去做時,你會發現分頁、編輯等功能都要靠程式碼來實現,ListView在這點上方便許多是吧。
 
 
本文範例下載位置
 
http://code6421.myweb.hinet.net/ASPNET35/ListViewDemo.zip
 
註:本文及範例使用的書及圖形為所屬出版社所有,如有不妥之處,請聯絡我,我會盡速移除。