Update ASP.NET Page after GridView DataBind
EDIT:
Apparently, part of the problem is that while an ASP:GridView has an OnDataBound() event (which you can use in the code-behind), the co开发者_StackOverflowrresponding HTML table that is produced does NOT, so you can attach that event to JavaScript. (Did I get that right?) So, that's why I'm having trouble with that bit of the issue. Back to the drawing board.I'm a desktop developer (WinForms with VB.NET) transitioning into ASP.NET development. My mind is really bending around the DOM and JavaScript and Session State and all of the stuff that goes along with web development. I'm not stupid, and I've done research (including hours of video watching and hundreds of pages of "Intro to ASP.NET" reading), but I keep hitting the wall with what seem to be fairly straightforward problems.
Basically, my current situation can be summed up as follows:
- I have a page that runs a very long process initiated by the user.
- The long process can take up to a few minutes , so I want to indicate to the user that SOMETHING is happening.
- When the process has completed, I either have: a. Results to show in a GridView b. No results to show
- If I have results to show, I want to display them.
- If I have no results to show, I want to show a label to the user that says "No results to show."
What's working:
- I have a basic page where the user selects start and end dates and kicks off the check process.
- The check process works fine (using LINQ-to-SQL logic developed for a desktop version of this program).
- I've got an UpdatePanel on my page which shows a label and an animated gif to indicate that something's happening.
- If I get results, they display appropriately in my GridView.
What's not working:
I'd love to give the user some sort of progress bar to indicate actual progress made toward completion rather than some endlessly-animating gif that doesn't indicate much at all. I could calculate this value quickly and easily, but can't figure out how to transfer said value from server to web page.
I can't figure out how to trigger an "unhide" event for the label. The long-running process is in a button's click event handler, where I run my custom code and generate a DataTable, which I then save as a session variable, assign it as the GridView's DataSource and call GridView.DataBind(). When I try to determine the contents of the DataTable and hide/reveal the label there, nothing seems to happen.
Problem #2 is really what I need to figure out in order to publish this web site. I'm assuming it involves a JavaScript solution, and I've tried some stuff, but I find that I'm truly guessing and don't have a good grasp on what the solution should resemble.
Here's the label I'd like to selectively reveal/make visible:
<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>
Here's a JavaScript function I'm trying to test:
<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>
Problem: This fails (databound not a member of 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>
What am I missing?
Thanks!!!!
For problem #1, there are a whole bunch of free Javascript progress bars out there. As for your value that you can't retrieve, try this:
<asp:Label ID="ProgressValue" runat="server" visible="false" />
And in your code behind.
ProgressValue.Text = //Your value from your database.
And just reference it from your Javascript there.
For your second problem, can't you just do in your code behind (written in C#)
//Process here
if(IDofGridView.Rows != null)
{
lblNoMissing.Visible = true;
}
Or am I missing something?
For #2, set style.visibility="visible" See: http://www.w3schools.com/cssref/pr_class_visibility.asp for valid values.
For #1, you can use an update panel with a timer for refreshing it. The server can simply add the current status to that users Session. The update panel code reads the session and shows the result.
So, I'm not sure I solved this exactly the way I wanted, but I have a working version. Here's what I did (for others who might find this useful):
I have abandoned my plans for #1 for now. I just simply don't have the time to continue looking into this issue right now. I'm bummed, though, because it seems like this is something a lot of people need to do, but I can't find a cookie cutter solution. Seems weird to me. Maybe I'm still missing some key info that would make it easy.
I have a GridView, a progress Label, an animated gif and a "no results" Label that I want to show/hide at various times. What ended up working for me was to place them all in UpdatePanels and simply show/hide them in my code-behind. It's kind of starting to make sense, but changing the visibility of a control from the code-behind when the control to change is OUTSIDE of an UpdatePanel but the code is initiated FROM INSIDE an UpdatePanel seems like a barrier that can't be crossed. That is, when my "no missing" Label was OUTSIDE of an UpdatePanel, the long-running process (started by a button INSIDE the UpdatePanel) couldn't change its visibility. (Does that make sense? Anyone want to correct that?)
Thanks for reading! Thanks for the ideas!
Edit:
OK, so I'm apparently wrong again. The code that shows/hides my Label and GridView has nothing to do with any code executed in the long-running process in the code-behind file.
Here's the code that actually does what I want (code is in 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>
The code related to "_messageSpan" is to prevent subsequent button clicks from starting the long-running process again (and also notify the user that it's still running).
So, since it is never correct for either of my items to be showing during a non-AsyncPostBack, I simply try to get the items and, if I get them, set them hidden. Now my page is behaving correctly. This may be some hacky code, but the page at least looks the way I want it!
精彩评论