在 GridView DataBind 之后更新 ASP.NET 页面

Posted

技术标签:

【中文标题】在 GridView DataBind 之后更新 ASP.NET 页面【英文标题】:Update ASP.NET Page after GridView DataBind 【发布时间】:2011-11-26 06:52:55 【问题描述】:

编辑: 显然,问题的一部分在于,虽然 ASP:GridView 有一个 OnDataBound() 事件(您可以在代码隐藏中使用),但生成的相应 html 表没有,因此您可以将该事件附加到 javascript。 (我做对了吗?)所以,这就是我在这个问题上遇到麻烦的原因。回到绘图板。


我是一名桌面开发人员(带有 VB.NET 的 WinForms)正在过渡到 ASP.NET 开发。我的思绪真的围绕着 DOM、JavaScript 和会话状态以及与 Web 开发相关的所有东西。我并不愚蠢,而且我已经完成了研究(包括观看数小时的视频和阅读数百页的“ASP.NET 简介”),但我总是遇到一些看似相当简单的问题。

基本上我现在的情况可以总结如下:

    我有一个页面运行一个由用户启动的很长的进程。 这个漫长的过程可能需要几分钟,所以我想向用户指出正在发生的事情。 该过程完成后,我要么有: 一种。在 GridView 中显示的结果 湾。没有可显示的结果 如果我有结果要显示,我想显示它们。 如果我没有要显示的结果,我想向用户显示一个标签,上面写着“没有要显示的结果”。

什么工作:

    我有一个基本页面,用户可以在其中选择开始和结束日期并开始检查过程。 检查过程运行良好(使用为此程序的桌面版本开发的 LINQ-to-SQL 逻辑)。 我的页面上有一个 UpdatePanel,它显示一个标签和一个动画 gif 来指示正在发生的事情。 如果我得到结果,它们会在我的 GridView 中正确显示。

什么不工作:

    我很乐意为用户提供某种进度条来指示完成的实际进度,而不是一些无休止的动画 gif,它根本没有太多指示。我可以快速轻松地计算出这个值,但不知道如何将这个值从服务器传输到网页。

    我不知道如何触发标签的“取消隐藏”事件。长时间运行的过程在按钮的单击事件处理程序中,我在其中运行我的自定义代码并生成一个 DataTable,然后我将其保存为会话变量,将其分配为 GridView 的 DataSource 并调用 GridView.DataBind()。当我尝试确定 DataTable 的内容并在那里隐藏/显示标签时,似乎什么也没发生。

问题 #2 是我真正需要弄清楚才能发布此网站的问题。我假设它涉及一个 JavaScript 解决方案,并且我尝试了一些东西,但我发现我真的是在猜测,并没有很好地掌握解决方案应该是什么样的。

这是我想选择性地显示/显示的标签:

<tr>
    <td colspan="2" align="center">
        <h2><asp:Label runat="server" ID="lblNoMissing" Text="No Missing Documentation Found" Visible="false"></asp:Label></h2>
    </td>
</tr>

这是我正在尝试测试的 JavaScript 函数:

<script type="text/javascript">
    function databound() 
        var gridViewID = '<%=_gridView1.ClientID%>';
        var labelID = '<%=lblNoMissing.ClientID%>';
        var gridView = document.getElementById(gridViewID);
        if (gridView.rows.length > 0) 
            $get(labelID).style.visibility = "false";
         else 
            $get(labelID).style.visibility = "true";
        
    
</script>

问题:失败(数据绑定不是 Default.aspx 的成员):

<asp:GridView ID="_gridView1" runat="server"
    AllowSorting="True" AutoGenerateColumns="False" CellPadding="4" 
    ForeColor="#333333" GridLines="Horizontal" PageSize="20" OnDataBound="databound();">
// Rest of GridView definition removed
</asp:GridView>

我错过了什么?

谢谢!!!!

【问题讨论】:

【参考方案1】:

对于 #2,设置 style.visibility="visible" 见:http://www.w3schools.com/cs-s-ref/pr_class_visibility.asp 获取有效值。

对于#1,您可以使用带有计时器的更新面板来刷新它。服务器可以简单地将当前状态添加到该用户的会话中。更新面板代码读取会话并显示结果。

【讨论】:

对不起,如果我没有说清楚,但我无法弄清楚如何让 databound() 工作。如图所示,当我将它放在我的 aspx 文件中时,我收到错误“数据绑定不是 Default.aspx 的成员”。尽管我试图模仿我见过的其他示例,但我似乎无法弄清楚如何将“databound()”作为 JavaScript 函数添加到我的页面。想法?【参考方案2】:

对于问题 #1,有一大堆免费的 Javascript 进度条。至于你无法找回的值,试试这个:

<asp:Label ID="ProgressValue" runat="server" visible="false" /> 

在你的代码后面。

ProgressValue.Text = //Your value from your database. 

只需从您的 Javascript 中引用它即可。

对于你的第二个问题,你不能只在你的代码后面做(用 C# 编写)

//Process here
if(IDofGridView.Rows != null) 

    lblNoMissing.Visible = true; 

或者我错过了什么?

【讨论】:

我也是这么想的!问题是,正如我在上面试图说明的那样,当我在漫长的过程结束时调用它时,设置 lblNoMissing.Visible 似乎没有做任何事情。我说 SEEM 是因为我对 ASP.NET 还很陌生,可能会遗漏一些东西。 UpdatePanel 中的 Button 生成长流程是否重要? 我不这么认为。我可能是错的(我对这一切也还是比较陌生),但除非你在进行中的 if 语句周围有 if(!IsPostBack) 之类的东西,否则它仍然应该呈现。 另外,当你渲染你的页面时,你会收到 javascript 错误吗?在您的 if(gridView.rows.length > 0) 中,如果您没有任何行,它不会取消引用空对象并出错吗? 我将此标记为答案,因为一旦我发现我需要将 lblNoMissing 放在 UpdatePanel 中,发布的代码就会起作用。我有点已经有了这段代码,但是这篇文章让我一直在努力解决这个问题,所以它得到了积分!谢谢!【参考方案3】:

所以,我不确定我是否完全按照我想要的方式解决了这个问题,但我有一个工作版本。这是我所做的(对于可能觉得这很有用的其他人):

    我暂时放弃了#1 的计划。我只是现在没有时间继续研究这个问题。不过,我很沮丧,因为这似乎是很多人需要做的事情,但我找不到千篇一律的解决方案。对我来说似乎很奇怪。也许我仍然遗漏了一些可以简化操作的关键信息。

    我有一个 GridView、一个进度标签、一个动画 gif 和一个“无结果”标签,我想在不同时间显示/隐藏。最终对我有用的是将它们全部放在 UpdatePanels 中,然后在我的代码隐藏中简单地显示/隐藏它们。这有点开始有意义,但是当要更改的控件位于 UpdatePanel 外部但代码是从 UpdatePanel 内部启动时,从代码隐藏更改控件的可见性似乎是无法跨越的障碍。也就是说,当我的“不丢失”标签位于 UpdatePanel 外部时,长时间运行的过程(由 UpdatePanel 内部的按钮启动)无法更改其可见性。 (这有意义吗?有人想纠正吗?)

感谢阅读!感谢您的想法!


编辑: 好的,所以我显然又错了。显示/隐藏我的 Label 和 GridView 的代码与代码隐藏文件中长时间运行的进程中执行的任何代码无关。

这是我真正想要的代码(代码在 Default.aspx 中):

<script type="text/javascript" >
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(CheckStatus);

function CheckStatus(sender, args) 
    var prm = Sys.WebForms.PageRequestManager.getInstance();

    if (prm.get_isInAsyncPostBack()) 
        args.set_cancel(true); // stop request from being sent
        $get("_messageSpan").innerHTML = "<h2>The last request is still processing.</h2>";
    
    else 
        var lbl = document.getElementById('<%=lblNoMissing.ClientID%>');
        if (lbl) 
            lbl.style.visibility = "hidden";
        
        var gview = document.getElementById('<%=_gridView1.ClientID%>');
        if (gview) 
            gview.style.visibility = "hidden";
        
        $get("_messageSpan").innerHTML = "";
    

</script>

与“_messageSpan”相关的代码是为了防止后续的按钮点击再次启动长时间运行的进程(同时也通知用户它仍在运行)。

因此,由于在非 AsyncPostBack 期间显示我的任何一个项目都是不正确的,我只是尝试获取这些项目,如果我得到它们,将它们设置为隐藏。现在我的页面运行正常。这可能是一些 hacky 代码,但页面至少看起来像我想要的那样!

【讨论】:

以上是关于在 GridView DataBind 之后更新 ASP.NET 页面的主要内容,如果未能解决你的问题,请参考以下文章

在运行时向 Gridview 动态添加行

C# GridView使用方法

GridView 行编辑事件的基础问题

gridview 的差异清除功能

EmptyDataTemplate 和 EmptyDataText 在 GridView 中不起作用

在DataBind之后添加列值