65.9K
CodeProject 正在变化。 阅读更多。
Home

用于管理带图标显示项的列表的 AJAX 图片列表控件

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (2投票s)

2007年12月18日

GPL3

4分钟阅读

viewsIcon

52883

downloadIcon

376

一个受 WinForms 的 ListView 启发并实现了 ASP.NET AJAX Extensions 1.0 的 ASP.NET 服务器控件。

ImageList in run mode

引言

我们的目标是提供一种在浏览器中管理小型项目列表的方法,包括添加和删除项目,其中最终列表可以发布到 ASP.NET 服务器。此功能由一个 `ImageList` 控件完成,该控件受到 WinForms 的 `ListView` 控件的启发。我们的环境是 Windows 和 IIS 上的 ASP.NET 2.0,我们的图像列表使用 ASP.NET AJAX Extensions 1.0,您可以从此处下载并安装。

背景

本文引用了“Memba Velodoc XP Edition”的开源控件,您可以从此处下载(此页面提供了 Codeplex、Google code 和 Sourceforge.NET 的链接),并根据 GPL 许可证分发。这些控件包含本文中使用的图像列表。您可以在此链接实时体验这些控件。

使用代码

在 Visual Studio 2005 中,创建一个新的 ASP.NET AJAX-Enabled Web Site,并添加对包含 `ImageList` 服务器控件的 *Memba.WebControls.XP.dll* 的引用。*Memba.WebControls.XP.dll* 是 Memba Velodoc XP Edition 的一部分。源代码可在上述下载位置获取。

打开 *Default.aspx* 页面,并通过将其添加到工具箱后拖放控件,或直接在现有 `<form>` 标签之间添加以下代码来添加 `ImageList` 服务器控件。

<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager" runat="server">
    <Scripts>
        <asp:ScriptReference Path="~/scripts/Memba.Utils.js" />
    </Scripts>
</asp:ScriptManager>
<table border="0" cellpadding="0" cellspacing="5">
    <tr>
        <td>
            <!-- ImageList -->
            <mbui:ImageList ID="ImageList1" runat="server"
                CssClass="cssList"
                ItemCssClass="cssItem"
                ItemHoverCssClass="cssItemHover"
                ImageCssClass="cssImage"
                TextCssClass="cssText"
                RemoveCssClass="cssRemove"
                RemoveTooltip="Remove from selection"
                LinesOfText="2"
                Height="92px"
                Width="300px">
            </mbui:ImageList>
            <!-- ImageList -->
        </td>
        <td align="center">
            <input id="txtItem" type="text" value="new item"
                style="width:100px;" />
            <input id="btnNew" type="button" value="New"
                style="width:100px;" /><br /> 
            <input id="btnCopy" type="button" value="Copy >>"
                style="width:100px;" /><br />
            <asp:Button ID="btnSubmit" runat="server" Text="Submit"
                style="width:100px;" OnClick="btnSubmit_Click" />
        </td>
        <td>
            <!-- ImageList -->
            <mbui:ImageList ID="ImageList2" runat="server"
                CssClass="cssList"
                ItemCssClass="cssItem"
                ItemHoverCssClass="cssItemHover"
                ImageCssClass="cssImage"
                TextCssClass="cssText"
                RemoveCssClass="cssRemove"
                RemoveTooltip="Remove from selection"
                LinesOfText="2"
                Height="92px"
                Width="300px">
            </mbui:ImageList>
            <!-- ImageList -->
        </td>
    </tr>
</table>
<textarea id="TraceConsole" cols="100" rows="20"></textarea>
</form>

该表单还包括一个 HTML 文本框(`txtItem`)、两个 HTML 按钮(`btnNew` 和 `btnCopy`)以及一个 ASP.NET 提交按钮(`btnSubmit`)。

您可能需要在页面顶部使用以下语句注册标签前缀

<%@ Register Assembly="Memba.WebControls.XP" 
    Namespace="Memba.WebControls" TagPrefix="mbui" %>

确保添加对 *Memba.Utils.js* 的脚本引用,该文件包含在 JavaScript 中创建 GUID 所必需的实用函数。

`ImageList` 控件是一个 `DIV`,它嵌入了一系列浮动的 `DIV`,每个 `DIV` 代表一个项目。每个项目 `DIV` 都包含一个图像、一个标签和一个删除图标。在页面 `</head>` 结束标签的正上方添加以下样式

<style type="text/css">
<!--
div.cssList
{
    position:fixed;
    overflow:auto;
    height:92px;
    border:1px solid #0F0000;
    background-color:#FFFFFF;
    clear:both;
}
div.cssItem
{
    position:relative;
    width:70px;
    height:70px;
    padding:5px;
    margin:5px;
    text-align:center;
    border:1px solid #FFFFFF;
    background-color:#FFFFFF;
    float:left;
}
div.cssItemHover
{
    position:relative;
    width:70px;
    height:70px;
    padding:5px;
    margin:5px;
    text-align:center;
    border:solid 1px #DCDCDC;
    background-color:#FAFAFA;
    float:left;
}
img.cssImage
{
    height:32px;
    width:32px;
    border:0px;
}
div.cssText
{
    font-family:Arial, Helvetica, sans-serif;
    font-size:9px;
    white-space:normal;
}
img.cssRemove
{
    position:absolute;
    top:64px;
    left:64px;
    height:16px;
    width:16px;
    border:0px;
    z-index:10;
    cursor:pointer;
}
//-->
</style>

您的 `ImageList` 控件现在应如下所示

ImageList in design mode

显然,您可以使用服务器端代码设置列表内容。打开名为 *Default.aspx.cs* 的代码隐藏文件,并实现 `Page_Load` 事件处理程序,如下所示

protected void Page_Load(object sender, EventArgs e)
{
    //Initialize ImageList1 with a new item
    ImageList1.ImageListItemCollection.Add(
        new Memba.WebControls.ImageListItem(
            Guid.NewGuid().ToString(),
            this.ResolveClientUrl("~/images/angel.gif"),
            "item #1"
        )
    );
}

按 F5 运行页面,并检查列表中是否有一个项目。您需要一个图像文件位于上述代码片段中指定的位置。

双击 ASP.NET 提交按钮,并实现 `Click` 事件处理程序,如下所示

protected void btnSubmit_Click(object sender, EventArgs e)
{
    //List the content of ImageList1
    Response.Write("<strong>ImageList1</strong>");
    if (ImageList1.ImageListItemCollection.Count > 0)
    {
        Response.Write("<ul>");
        foreach (Memba.WebControls.ImageListItem objImageListItem
            in ImageList1.ImageListItemCollection)
        {
            Response.Write("<li>" + 
              objImageListItem.Text + "</li>");
        }
        Response.Write("</ul>");
    }
    //List the content of ImageList2
    Response.Write("<strong>ImageList2</strong>");
    if (ImageList2.ImageListItemCollection.Count > 0)
    {
        Response.Write("<ul>");
        foreach (Memba.WebControls.ImageListItem objImageListItem
            in ImageList2.ImageListItemCollection)
        {
            Response.Write("<li>" + 
              objImageListItem.Text + "</li>");
        }
        Response.Write("</ul>");
    }
}

点击 F5 运行页面,然后点击提交按钮。响应应以项目符号列表显示两个图像列表的内容。观察到在回发时,图像列表保持其状态。

`ImageList` 控件在一个 HTML 隐藏字段中存储一个用 JSON 序列化的项目数组。

  • 当您在页面加载时在服务器端添加项目时,这些项目只是被添加到隐藏字段中;
  • 当页面在浏览器中渲染时,内置在控件中的 JavaScript 代码会读取隐藏字段中序列化的数组以渲染图像;
  • 当使用控件的客户端 API 时,您只需向序列化到隐藏字段中的数组添加或删除项目;
  • 当您回发页面时,隐藏字段会被回发,并且控件的服务器端代码允许您访问项目集合,该集合是从隐藏字段中读取的。

图像列表的内容也可以使用 JavaScript 代码在客户端更改。在页面 `</body>` 结束标签之前添加以下脚本

<script type="text/javascript">
<!--
// Declare global variables for the various controls
var g_ImageList1;
var g_ImageList2;
var g_txtItem;
var g_btnNew;
var g_btnCopy;
//pageLoad function of ASP.NET Ajax Extensions framework
function pageLoad()
{
    //get a reference to the ImageList controls
    g_ImageList1 = $find("<%= ImageList1.ClientID %>");
    g_ImageList2 = $find("<%= ImageList2.ClientID %>");
    //Add event handlers for the ImageList controls
    if(g_ImageList1)
        g_ImageList1.add_remove(onRemove);
    //Get references to html controls
    g_txtItem = $get("txtItem");
    g_btnNew = $get("btnNew");
    g_btnCopy = $get("btnCopy");
    //Add event handlers for the click event of both html buttons
    if(g_btnNew)
        $addHandler(g_btnNew, "click", onBtnNew);
    if(g_btnCopy)
        $addHandler(g_btnCopy, "click", onBtnCopy); 
}
//pageUnload function of ASP.NET Ajax Extensions framework
function pageUnload()
{
    //Clear event handlers
    if(g_ImageList1)
        g_ImageList1.remove_remove(onRemove);
    if(g_btnNew)
        $clearHandlers(g_btnNew);
    if(g_btnCopy)
        $clearHandlers(g_btnCopy); 
}
//Remove event handler for the ImageList controls
function onRemove(sender, args)
{
    if((g_ImageList2) && (g_ImageList2.get_item(args.get_key())))
        g_ImageList2.remove_item(args.get_key());
}
//click event handler for the btnNew button
function onBtnNew()
{
    if(g_ImageList1 && g_txtItem)
    {
        //Instantiate a new item
        var item = new Memba.WebControls.ImageListItem(
            Memba.Utils.newGuid(),
            '<%= this.ResolveClientUrl("~/images/angel.gif") %>',
            g_txtItem.value
            );
        //Add the item to the list
        g_ImageList1.add_item(item);
    }
}
//click event handler for the btnCopy button
function onBtnCopy()
{
    if(g_ImageList1 && g_ImageList2)
    {
        //Clone the array in ImageList1
        var _arr = Array.clone(g_ImageList1.get_items());
        for(var i = 0; i < _arr.length; i++)
        {
            //Copy any non-existing item to ImageList2
           if(g_ImageList2.get_item(_arr[i].get_key()) == null)
               g_ImageList2.add_item(_arr[i]);
        }
    }
}
//-->
</script>

ASP.NET AJAX 扩展提供了两个重要的 JavaScript 事件处理程序

  • pageLoad 由框架在页面 DOM 和脚本加载并初始化时调用。这是一个获取控件引用和添加事件处理程序的理想位置。
  • pageUnload 由框架在页面卸载时调用。建议在此阶段清除处理程序。

该脚本为两个 HTML 按钮(`btnAdd` 和 `btnCopy`)的 `Click` 事件实现了事件处理程序。`btnAdd` 的 `Click` 事件处理程序向第一个图像列表添加一个新项目。`btnCopy` 的 `Click` 事件处理程序将 `ImageList1` 的内容复制到 `ImageList2`。

该脚本还为第一个图像列表的移除事件实现了一个事件处理程序。每次从第一个图像列表中移除项目时,如果该项目存在,它也会从第二个图像列表中移除。

按 F5 运行项目,然后单击各种按钮以体验 `ImageList`。

关注点

此图像列表是列表框的灵活且用户友好的替代方案,用于管理小型项目列表。对于更高级的开发人员,图像列表的源代码可在CodeplexGoogle codeSourceforge.NET 上获取,并附有非常详细的注释。

历史

  • 版本 1.0 - 日期:2007 年 12 月 18 日。
© . All rights reserved.