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

网格实时刷新

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.24/5 (9投票s)

2008年1月12日

CPOL

4分钟阅读

viewsIcon

42360

downloadIcon

603

一个经典的场景,在网上至今没有找到一个完美的解决方案。

场景

在一个子网页的 ContentPlaceHolder (ContentPlaceHolder1) 中,我放置了以下控件:

  • 一个 GridView 控件 (GridView1),用于显示 Northwind 数据库 Categories 表中的数据行。
  • 一个 SqlDataSource (SqlDataSource1),用于从数据库中获取数据并绑定到 GridView
  • 一个 LinkButton (LinkButton1),允许用户向 Categories 表中插入新数据行。
  • 一个 Panel (Panel1) 和一个 ModalPopupExtender (ModalPopupExtender1) 控件,用于提供向数据库表中插入新数据的界面。ModalPopupExtenderPopupControlID 属性设置为 Panel1。这将导致 Panel1 面板在屏幕上弹出。
  • 最后,GridView 被包含在一个 UpdatePanel (UpdatePanel1) 中。

每次向数据库插入新数据行时,我们希望以平滑的 AJAX 方式刷新 GridView 数据,而无需刷新整个网页。如何做到这一点?请继续阅读以了解详情。

解决方案

要添加新数据行,用户需要单击 LinkButton。由于 LinkButtonModalPopupExtenderTargetControlID 属性的值,因此单击 LinkButton1 会有效地使 Panel1 面板在屏幕上弹出。

Panel1 包含合适的数据输入文本框、OK 按钮 (OkButton) 和 Cancel 按钮 (CancelButton)。这两个按钮分别通过 OkControlIDCancelControlID 属性连接到 ModalPopupExtender。此外,OnOkScript="onOkClick()" 属性声明会在用户单击 OkButton 按钮时执行 onOkClick() JavaScript 函数。

onOkClick() JavaScript 函数在客户端执行。它收集用户输入,并异步调用 DB Web 服务中的 DB.AddCategory Web (和脚本) 方法。DB.AddCategory 将新数据行插入数据库。由于这是一个异步调用,因此也定义了成功 (onAddSuccess) 和失败 (onAddFailure) 回调函数。

请注意 onAddSuccess 回调函数中的 _doPostBack 调用。这是调用 OkButton 控件的服务器端回发所需的代码。请注意,由于我们在 ContentPlaceHolder 中,OkButton 的 ID 可能是 "ctl00ContentPlaceHolder01OkButton" 这样的形式,JavaScript 代码必须知道这一点。

此时,将执行 OkButton_Click 方法的服务器端代码。它所做的就是让数据绑定的 GridView 重新绑定到 SqlDataSource。通常,这将导致整个网页在浏览器中刷新,这是不希望的。我们真正想要的是在不刷新页面的情况下刷新 GridView。这就是我将 GridView 放置在 UpdatePanel 控件中的原因。

关键问题

现在最大的问题是如何在新数据行插入数据库后立即更新 UpdatePanel。长话短说,我们所要做的就是设置正确的触发器。但它会是哪个控件呢?

关键答案

如果您认为 LinkButton 应该是触发器,那么您就像我一样,不幸的是,您错了。答案是 Panel1 中的 OkButton 控件必须是触发 UpdatePanel 更新的控件。这就是为什么在异步 Web 服务调用完成后,我们立即调用 OkButton 的回发。回发会导致触发器触发,然后,瞧!UpdatePanel 及其内容 (新数据行会显示为网格行) 会得到更新。设置触发器非常简单。

<Triggers>
    <ajax:AsyncPostBackTrigger ControlID="OkButton" EventName="Click" />
</Triggers>

最后但同样重要的是,请确保将 UpdatePanelUpdateMode 属性设置为 "Conditional"。另外,不要忘记使 DB Web 服务可供 JavaScript 代码访问。

<ajax:ScriptManager ID="ScriptManager1" runat="server">
    <Services>
        <ajax:ServiceReference Path="DB.asmx" />
    </Services>
</ajax:ScriptManager>

总结一下,您必须记住以下一系列事件:

(1) 用户单击 LinkButton -> (2) ModalPopupExtender 弹出 Panel1。用户输入数据并单击 OK 按钮 -> (3) 执行 onOkClick() JavaScript 代码。进行异步 Web 服务调用,并将新数据行插入数据库。成功后,控制权返回到 onAddSuccess 回调函数,该函数 -> (4) 触发一个回发以调用 OK 按钮的服务器端代码 -> (5) 由于 OK 按钮是 UpdatePanel 的触发器,回发有效地导致 UpdatePanel 及其内容得到更新。

关注点

  1. 母版页无处不在。在此场景中,所有控件都放置在子页面的 ContentPlaceHolder 中。这本身就带来了控件 ID 修改的效果。如果您想从 JavaScript 客户端代码调用控件回发,则必须小心。
  2. 在向数据库插入数据行后,必须刷新数据绑定的 GridView。由于 GridView 位于 UpdatePanel 中,因此这等同于更新 UpdatePanel。您只能通过放置适当的触发器来实现这一点。在此场景中,乍一看这可能并不明显。

我为什么写这个

我花了整整一周时间才解决这个问题。在互联网上搜索只能帮助我解决零碎的问题。似乎找不到一个直接而完整的答案。这就是为什么我决定为社区贡献这篇文章。提问很容易,但提供解决方案可能很难。

© . All rights reserved.