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

GridView 中的可展开面板

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (45投票s)

2008年9月17日

CPOL

3分钟阅读

viewsIcon

313927

downloadIcon

12661

在 GridView 中展开详细信息面板的另一种方法。

引言

几周前,一位客户问我:“我们需要一个简单的列表,并且我们需要点击查看列表中的详细信息 - 不是弹出窗口 - 不是另一个页面 - 不是重新加载整个页面”。我开始搜索、阅读、测试。 我找到了一些有趣的文章和示例,但不是我的客户真正想要的。 然后我想:我可以合并一些解决方案,也许可以满足客户的需求。 AJAX DynamicPopulate 扩展器提供了该机制。 让我们打开源代码并学习。 一些有趣的文章提出了一些好主意。 让我们阅读和学习。

我想在这篇文章中分享这项工作的成果。

您可以在这里看到示例项目运行(仅使用模拟数据)。

背景

当 AJAX DynamicPopulate 扩展器启动时,它会调用某个页面或 Web 服务上的一个方法,接收一些结果,并填充一个控件。

我们可以使用 JavaScript 函数来启动扩展器,并且可以捕获结果并填充另一个控件。当用户单击网格第一列中的按钮时,JavaScript 函数会被激活。

Using the Code

主页面有一个包含三列的 GridView:一个模拟按钮的图像,用于显示和隐藏详细信息,商店名称和销售额总和。

场景是Adventure Works Cycles,这是一家虚构的大型跨国制造公司。 网格显示了顶级商店。 当用户单击按钮时,会展开一个面板并显示前五个模型。

图像/按钮的 onclick 事件调用一个 JavaScript 函数 (ExpandModels),其中包含以下参数:客户 ID、网格视图的行、目标面板和单击的按钮。

// Default.aspx.cs :
protected void gridStores_RowDataBound(object sender, GridViewRowEventArgs e) {
...
Image btn = gridViewRow.FindControl("imgModel") as Image;

btn.Attributes["onClick"] = String.Format(CultureInfo.InvariantCulture,
    "ExpandModels('{0}', '{1}', '{2}', '{3}');",
    contextKey,             // customerID + some data
    newRow.ClientID,        // Row of gridview, below the row that was clicked
    internalPanel.ClientID, // Destination panel, wich will receive the details
    btn.ClientID);          // The clicked button
...
}

JavaScript 函数 ExpandModels 执行一些准备工作,并启动 DynamicPopulate 扩展器的 'behavior' dpBehaviorModpopulate 方法,传递客户 ID。 'behavior' 将向 WebMethod ExpandModelsService 发送回调,该 WebMethod 将构建一个 HTML 表格并将其发送回浏览器。

// ExpandPanel.js :
var expPainelId    = '';  // ID of the internal panel where the details will be inserted
var expPainelAuxId = 'painelAux';  // Receives the results from the WebMethod

function ExpandModels(customerId, trId, painelId, buttonId) {
...
var tr = $get(trId).style;
tr.display='block';                         // Shows the panel ('table-row' for Firefox)
lastBehavior = $find('dpBehaviorMod');
expPainelId = painelId;
lastBehavior.add_populated(ShowTopModels);  // Sets the handle
lastBehavior.populate(customerId);          // Calls the WebMethod
}

<!-- Default.aspx -->
<cc1:DynamicPopulateExtender ID="dinPopMod"
                             runat="server"
                             BehaviorID="dpBehaviorMod"
                             CacheDynamicResults="false"
                             ClearContentsDuringUpdate="true"
                             EnableViewState="False"
                             ServiceMethod="ExpandModelsService"
                             TargetControlID="painelAux">
</cc1:DynamicPopulateExtender>

<asp:Panel ID="painelAux"
           runat="server"
           EnableViewState="false"
           Style="background-image:url('img/loading.gif'); 
                  background-repeat: no-repeat; display: none">
</asp:Panel>

当扩展器返回时,它会填充辅助面板 'painelAux'(由属性 TargetControlID 指示),然后另一个 JavaScript 函数 (ShowTopModels) 将结果复制到目标面板。 面板 ID 由函数 ExpandModels 保存在变量 expPainelId 中。

// ExpandPanel.js :
function ShowTopModels(s, e) {
    // The internal panel where the details will be inserted
    var p1 = $get(expPainelId);
    // The aux panel filled by the DynamicPopulateExtender
    var p2 = $get(expPainelAuxId);
    ...
    // Details HTML table
    p1.innerHTML = p2.innerHTML;
    ...
}

在 web 方法内部,程序构建一个包含详细信息的简单 HTML 表格。

[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod]
public static string ExpandModelsService(string contextKey) {
...
    StringBuilder sb = new StringBuilder("<table class = 'tab-mod'> \n"
    + "<tr> \n"
    + "<th>Model</th> \n"
    + "<th>Qty</th> \n"
    + "<th>Total price</th> \n"
    + "<th>Last sale</th> \n"
    + "</tr> \n",
    topModels.Count * 180);
...
    sb.Append("<tr> \n");
    sb.AppendFormat(CultureInfo.CurrentCulture,
        "<td>{0}</td> ",
        modelRow.Name);
...
    sb.Append("</table> \n");

    return sb.ToString();
}

以上代码片段摘自示例项目并经过简化。 完整的源代码可供下载。

关注点

当页面发送到浏览器时,只会发送主列表(商店)。 当用户单击每一行上的按钮时,模型将动态发送。 我们可以使用另一种方法在第一次加载所有数据,然后在 onclick 事件中隐藏/显示。 这种方法可能会导致加载整个页面花费很长时间。

'loading.gif' 文件由面板 'painelAux' 预加载,以加快用户单击按钮时的显示速度。

我将 WebMethod ExpandModelsService 包含在 'Default.aspx' 中。 如果项目包含很多 WebMethod,我们可以创建一个或多个 'asmx' 文件来帮助我们组织项目。

结论

如果这篇文章能以任何形式帮助到您,我将很高兴。

当然,您可以在示例项目中找到许多错误、bug 和不太好的代码。 我提前感谢您的提示、建议和更正。

参考文献

已经有很多关于这个主题的好文章

© . All rights reserved.