Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

specific PostBack event not firing (handler not reached) after Page.Load fires (Page_Load is reached) successfully

Posted on 2006-05-22
26
Medium Priority
?
4,798 Views
Last Modified: 2012-08-14
Hi,

I'm having a problem with something that used to work.  I'm not sure what I did, but when I click on either of 2 buttons to submit, or on a DataGrid column header to submit/sort, the Page.Load event on the page does fire, but the handler/routine for the control that initiated the PostBack does NOT get called.

.ASPX file (3 controls in question):
---------------------------------------
<asp:datagrid id="MessagesDataGrid" runat="server"
      accessKey="M" tabIndex="13"
      Width="1081px" Height="30px" BorderWidth="1" CellPadding="2" BackColor="WhiteSmoke"
      AllowSorting="True"
      Font-Names="Arial" Font-Size="Medium">
      <AlternatingItemStyle BackColor="Gainsboro"></AlternatingItemStyle>
      <HeaderStyle Font-Bold="True" Height="30px" ForeColor="White" CssClass="ms-formlabel DataGridFixedHeader" BackColor="#000084"></HeaderStyle>
</asp:datagrid>

<button id="ButDismissAlerts"
      style="Z-INDEX: 105; LEFT: 928px; WIDTH: 104px; POSITION: absolute; TOP: 64px; HEIGHT: 40px"
      accessKey="D" tabIndex="11" type="button" runat="server">Dismiss Alerts</button>

<button id="ButGo"
      style="FONT-WEIGHT: bold; Z-INDEX: 109; LEFT: 484px; WIDTH: 60px; COLOR: rgb(255,255,255); POSITION: absolute; TOP: 71px; HEIGHT: 25px; BACKGROUND-COLOR: rgb(0,128,0)"
      accessKey="O" tabIndex="7" type="button" runat="server">Go</button>

.ASPX.CS code:
------------------
public class Messages : System.Web.UI.Page
{
      protected System.Web.UI.HtmlControls.HtmlButton ButDismissAlerts;
      protected System.Web.UI.WebControls.DataGrid MessagesDataGrid;
      protected System.Web.UI.HtmlControls.HtmlButton ButGo;

      override protected void OnInit(EventArgs e)
      {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
      }
            
      /// <summary>
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// </summary>
      private void InitializeComponent()
      {
            this.MessagesDataGrid.SortCommand += new System.Web.UI.WebControls.DataGridSortCommandEventHandler(this.MessagesDataGrid_SortCommand);
            this.ButGo.ServerClick += new System.EventHandler(this.ButGo_ServerClick);
            this.ButDismissAlerts.ServerClick += new System.EventHandler(this.ButDismissAlerts_ServerClick);
            this.Load += new System.EventHandler(this.Page_Load);
      }

      private void Page_Load(object sender, System.EventArgs e)
      {
            // IsPostBack is true in the following cases:
            // - A new refresh period has been requested by clicking "Go".
            // - The "Dismiss Alerts" button has been clicked.
            // - A new sort has been requested by clicking a column header.
            if (IsPostBack)
            {
                  // Get/Bind the message data from the previous page.  Any refreshing of data or other
                  // processing will happen (subsequently) in the function that invoked the PostBack call.
                  MessagesDataGrid.DataSource = (DataView)Session["CurrentMessagesView"];
                  MessagesDataGrid.DataBind();
            }
            else
            {
                  MessagesDataGrid.DataSource = CreateMessagesDataSource();
                  MessagesDataGrid.DataBind();
            }
      }

      private DataView CreateMessagesDataSource()
      {
            // get data into dataset "ds"

            DataView dv = new DataView(ds.Tables[0]); // for now
            Session["CurrentMessagesView"] = new DataView(ds.Tables[0]); // for later (PostBack)

            return dv;
      }

      private void ButGo_ServerClick(object sender, System.EventArgs e)
      {
            // event handling code
      }

      private void ButDismissAlerts_ServerClick(object sender, System.EventArgs e)
      {
            // event handling code
      }

      private void MessagesDataGrid_SortCommand(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
      {
            DataView dv = (DataView)MessagesDataGrid.DataSource;
            dv.Sort = e.SortExpression;
            MessagesDataGrid.DataBind();
      }
}

I tried re-double-clicking on the two above buttons in the Designer view in VS2003 and they went straight to the handler routines as they should.  After recompiling, setting break point in Page_Load, and restarting, the code breaks there as it should for the initial load, then again on the PostBack as well when a button or the grid header is clicked.  BUT - breakpoints set in any of the handling routines never get reached.  It's not strictly a DataGrid issue - the buttons have the same problem.

What could cause the event handlers to no longer get called?  I've got to be doing something stupid, but I've been staring at it too long.  Hopefully it's some easy points for someone.  Thanks for any direction/help!
0
Comment
Question by:TruthHunter
  • 15
  • 7
  • 4
26 Comments
 
LVL 6

Expert Comment

by:fizch
ID: 16737103
Make sure that your controls have autopostback set to true for each of the components you want to handle the event for. Sometimes the designer gets a little crazy and you can lose some of your settings.
0
 

Author Comment

by:TruthHunter
ID: 16737142
Thanks for the amazingly fast reply, fizch!  Unfortunately, the DataGrid doesn't appear to actually have an AutoPostBack event, nor do the two HtmlButtons.  (I needed to implement them as HtmlButtons because I had to highlight access keys for them - a separate issue.)

FWIW, upon breaking in Page.Load on the PostBack, I did verify that the controls appear to be initiating the PostBack correctly, by checking the Page.Request.Params["__EVENTTARGET"] field.  In each case I saw the button name, or the grid name + column header name.

If I had any hair left I'd pull it out!
0
 
LVL 6

Expert Comment

by:fizch
ID: 16737196
You could always try creating your event handlers manually. Try putting the following lines of code in your page_load.

ButGo.Click += new System.EventHandler(ButGo_ServerClick);
ButDismissAlerts.Click += new System.EventHandler(ButDismissAlerts);
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 33

Assisted Solution

by:raterus
raterus earned 1000 total points
ID: 16737438
when you rebind your grid when the Page.IsPostBack, you run the risk of overwriting the event-handlers that would fire.  My suggestion is to NEVER, write something like this in Page_Load...

         if (IsPostBack)
          {
               // Get/Bind the message data from the previous page.  Any refreshing of data or other
               // processing will happen (subsequently) in the function that invoked the PostBack call.
               MessagesDataGrid.DataSource = (DataView)Session["CurrentMessagesView"];
               MessagesDataGrid.DataBind();
          }

You need to lose this quick if you have viewstate enabled on the DataGrid, it'll cause more problems than it's worth!
0
 

Author Comment

by:TruthHunter
ID: 16739003
Thanks for the replies.

raterus, I wondered about that and did comment out the code you mentioned (actually moving it to each of the control handlers), but to no avail.

Believe me, this used to work, even when the code was in Page_Load.  Are there any other scenarios where the event handlers would get trashed somehow?  Ill try the manual handlers next.  For the record though, I did verify that InitializeComponent() was being called and those event handlers did seem to get added.

This all seemed to stop working when a MS patch got automagically installed.  I hope they didn't trash something in the CLR.

Thanks again for the help so far.  I am grateful for any and all guidance and suggestions, as this is my first ASPX app.
0
 

Author Comment

by:TruthHunter
ID: 16739050
fizch, I tried to add the handlers manually in Page_Load (removing them from InitializeComponent() ), but again, to no avail.

Here's the directive from the top of the ASPX file.  I went back and checked and it was the same when things were working, too, but perhaps it will shed some light?  Could the validateRequest=false be screwing things up?  I'll try taking that out next.

<%@ Page language="c#" Codebehind="Messages.aspx.cs" AutoEventWireup="false" Inherits="LEMap.Messages" enableViewState="False" validateRequest="False"%>
0
 

Author Comment

by:TruthHunter
ID: 16739080
Nope.  Taking out validateRequest="False" from the page directive didn't help either.  In fact, the page wouldn't load without it included because another button outside the scope of this discussion apparently had some tags (i.e. <SPAN>) embedded and ASP.NET didn't like it.  (Probably why the previous developer turned off validation.  It's an internal-only app anyway.)

Other pages' handlers seem to be working fine.  I'm off to fine-tooth comb for any noticeable differences...
0
 

Author Comment

by:TruthHunter
ID: 16739321
I found this at:  http://www.extremeexperts.com/Net/Articles/ViewState.aspx
------------------------------
Viewstate in DataGrid

If you have Set EnableViewState to true for a DataGrid which is having thousands of record. Then you will end up having viewstate size more than 10 KBytes. But if you disable viewstate, you will not be able to fire any events in DataGrid. Postback and acting on postback relies on Viewstate. So if it is readonly datagrid and if you are not going to use paging and sorting provided by datagrid, then you can disable viewstate. But if you want use above mentioned feature of DataGrid, then you can not disable ViewState in DataGrid. So to avoid excessive load on client machine because of viewstate . You can disable viewstate for each item in DataGrid. Disabling can be done in two ways, one way is disabling each itemtemplate columns viewstate to false. Other way is by disabling viewstate for each datagrid item in Pre-Render event handler.
------------------------------

Should I go down this path of enabling view state in the Page directive, and then going through the DataGrid and setting each item's view state to false?  The DataGrid rows/items are  created dynamically from a DataSet - so I don't think they're available during the Pre-Render phase.  When the DataGrid's DataSource is set to the DataView from the DataSet, would that be a good time instead perhaps?

Just looking for tips before I go reworking chunks of code... thanks!
0
 
LVL 33

Expert Comment

by:raterus
ID: 16741832
I wouldn't mess with the viewstate quite yet, if anything keeping it on is going to help not hurt.

Can you repost your code after you moved the rebinding code out of page_load?  I'd like to see what you change, but still didn't work.  I'm still thinking this has to do with the grid, or certain parts of it being rebound before the events are fired, so the more code you can post the better!
0
 
LVL 6

Expert Comment

by:fizch
ID: 16742007
That's my bad. I didn't see that the buttons were getting events tied to them in the initialize component method. Have you tried adding a new button to see if that one responds?
0
 

Author Comment

by:TruthHunter
ID: 16742661
Thanks guys...

I came across this last night:  http://west-wind.com/weblog/posts/211.aspx

One entry in particular grabbed my attention:

----------------------------------------
I've solved one issue after a full two evenings of frustration.

The thing that caused my problem was that I was moving a datagrid around on the page in response to user requests. I think that because I was dropping the grid into a panel (server control) the post back wasn't able to find it.

My best guess is that this resulted in the HTML post back not matching some magical thing that needs to happen behind the scenes in order for .Net to process the post back page.

I solved the problem by moving other controls around the datagrid instead of moving it. I guess it's true that the world revolves around the data grid :D
----------------------------------------

I did move the grid (and also the buttons in question) down a number of pixels to make room for something else.  I'm wondering if that broke it; like I said, it used to work!  I'm going to delete, rebuild, re-add, rebuild, etc.  Then I promise to post more code (for example, the grid is inside a DIV - that's what actually had its coordinates/position moved).  Thanks for the suggestions so far... will let you know.
0
 

Author Comment

by:TruthHunter
ID: 16744008
OK...

Deleting and readding each control (2 buttons, DataGrid) didn't help.  I even tried adding a new HtmlButton on the page, but it didn't work (i.e. its ServerClick event did not fire after the Page.Load did fire).  A WebControls.Button did work (i.e. its Click event did fire after the Page.Load did fire) when added.

I did discover that I had a couple controls with the same Z-INDEX in their style - not exactly sure how that happened.  But changing all values to be unique and rebuilding didn't help either.

I also have been registering one of the buttons in question as the _EVENTTARGET at the end of Page_Load, in case the user hit return to submit the form.  But removing that Page.RegisterHiddenField() call didn't appear to help either.  Although I'm thinking maybe I should move it inside the IsPostBack check to be safe?

Grasping at straws... when I moved controls down, things overlapped a little in the designer (not on the final displayed page).  But adding a new HtmlButton in an "open" area of the page didn't work either.

So it looks like PostBack is just plain broken on this page.  It works fine on other pages (buttons, no grid).  Only this page has enableViewState set to false in the Page directives section.  But it used to work, even with this page directive.

So, here's more of the code.  Because it's long (as well as for the typical IP reasons), I've taken out most of the non-relevant parts (i.e. the parts that have always been working fine).  I'm going to start looking at ViewState stuff more now, and checking back here obviously.  Code follows:

=========================================================================================
Messages.aspx:
------------------
<%@ Page language="c#" Codebehind="Messages.aspx.cs" AutoEventWireup="false" Inherits="LEMap.Messages" enableViewState="False" validateRequest="False" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
      <HEAD>
            <title>xxxxx</title>
            <!-- Prevent caching of the page(back/forward) buttons! -->
            <% Response.CacheControl = "no-cache"; %>
            <% Response.AddHeader("Pragma", "no-cache"); %>
            <% Response.Expires = -1; %>
            <LINK href="xxxx.css" type="text/css" rel="stylesheet">
            <script language="JavaScript" src="AccessKeys.js"></script>
            <script language="JavaScript" src="ConfigureUserPreferences.js"></script>
            <script language="javascript">
            // Display the Configure Filters window.
            var ConfigureFiltersWindow = null;
            function ConfigureFilters(w, h)
            { // ...
            }
            // Display the Error Logs window.
            var DisplayErrorLogsWindow = null;
            function DisplayErrorLogs(w, h)
            { // ...
            }

            var savedScrollPos = null;
                  
            // this script is called to save the current scroll position in a cookie, so it can be restored the next
            // time we enter this window.
            function saveScrollPosToCookie()
            {      
                  savedScrollPos = document.all.DivMessages.scrollTop;
                  var the_cookie = "MessagesSavedPosition=" + escape(savedScrollPos);
                  document.cookie = the_cookie;
            }

            // this script is called to save the current scroll position to a local variable, so it can be restored the next
            // time the window gets focus.
            function saveScrollPos()
            {      
                  savedScrollPos = document.all.DivMessages.scrollTop;
            }

            // this script is called to restore the saved scroll position from a cookie, if any.
            function restoreScrollPosFromCookie()
            {      
                  var restoredScrollPos = null;
                  restoredScrollPos = readCookie("MessagesSavedPosition");
                  if (restoredScrollPos != false)
                  {
                        document.all.DivMessages.scrollTop = restoredScrollPos;
                        savedScrollPos = restoredScrollPos;
                  }
            }

            // this script is called to restore the saved scroll position from a local variable, if any.
            function restoreScrollPos()
            {      
                  if (savedScrollPos != null)
                  {
                        document.all.DivMessages.scrollTop = savedScrollPos;
                  }
            }

            // This script is called to read a particular cookie.  Note that a position of 0 appears to be false on return.
            function readCookie(name)
            {
                  if (document.cookie == '')
                  {    
                        // there's no cookie, so go no further
                        return false;
                  }
                  else
                  {
                        // there is a cookie
                        var firstChar, lastChar;
                        var theBigCookie = document.cookie;
                        firstChar = theBigCookie.indexOf(name);
                        // find the start of 'name'
                        if(firstChar != -1)
                        {
                              // if you found the cookie
                              firstChar += name.length + 1;
                              // skip 'name' and '='              
                              lastChar = theBigCookie.indexOf(';', firstChar);
                              // Find the end of the value string (i.e. the next ';').
                              if(lastChar == -1)
                              {
                                    lastChar = theBigCookie.length;
                              }
                              return unescape(theBigCookie.substring(firstChar, lastChar));
                        }
                        else
                        {
                              // If there was no cookie of that name, return false.
                              return false;
                        }
                  }
            }
            
            // This script closes any children window that are open when the window refreshes
            // or otherwise is about to close (such as a navigation to a different page).
            function closeChildren()
            { // ...
            }
            </script>
            <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
            <meta content="C#" name="CODE_LANGUAGE">
            <meta content="JavaScript" name="vs_defaultClientScript">
            <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
            <meta http-equiv=refresh content='<%=Session["RefreshPeriod"]%>'>
      </HEAD>
      <BODY onblur="saveScrollPosToCookie()" onfocus="restoreScrollPosFromCookie(); window.DivMessages.focus()"
            onload="highlightAccessKeys(); restoreScrollPosFromCookie(); window.DivMessages.focus()"
            onbeforeunload="closeChildren()" onunload="saveScrollPosToCookie()" ms_positioning="GridLayout">
            <TABLE id="Table2" style="Z-INDEX: 101; LEFT: 0px; POSITION: absolute; TOP: 8px" cellSpacing="1"
                  cellPadding="1" width="240" border="0">
                  <TR>
                        <TD><asp:image id="Image2" ImageUrl="logo.jpg" runat="server" Width="240px" Height="54px"></asp:image></TD>
                  </TR>
            </TABLE>
            <TABLE id="Table4" style="Z-INDEX: 102; LEFT: 280px; POSITION: absolute; TOP: 16px" cellSpacing="0"
                  cellPadding="1" border="0">
                  <TR vAlign="middle">
                        <TD><asp:hyperlink id="LinkToXXX" accessKey="U" tabIndex="1" runat="server" Font-Size="Medium"
                                    Font-Bold="True" NavigateUrl="XXX.aspx" ToolTip="XXX">XXX</asp:hyperlink></TD>
                        <TD><asp:label id="Label9" runat="server" ForeColor="Blue">&nbsp;&nbsp;|&nbsp;&nbsp;</asp:label></TD>
                        <TD><asp:label id="Label8" runat="server" Font-Size="Medium" Font-Bold="True" ForeColor="Black">Messages</asp:label></TD>
                        <TD><asp:label id="Label1" runat="server" ForeColor="Blue">&nbsp;&nbsp;|&nbsp;&nbsp;</asp:label></TD>
                        <TD><asp:hyperlink id="LinkToYYY" accessKey="T" tabIndex="2" runat="server" Font-Size="Medium"
                                    Font-Bold="True" NavigateUrl="YYY.aspx" ToolTip="YYY">YYY</asp:hyperlink></TD>
                        <TD>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
                        <TD><asp:hyperlink id="Hyperlink1" accessKey="L" tabIndex="3" runat="server" Font-Size="Small" Font-Bold="True"
                                    NavigateUrl="UserGuide.pdf" ToolTip="Open the User Guide" Target="_blank">Help</asp:hyperlink></TD>
                        <TD><asp:label id="Label7" runat="server" ForeColor="Blue">&nbsp;&nbsp;|&nbsp;&nbsp;</asp:label></TD>
                        <TD><asp:hyperlink id="Hyperlink2" accessKey="G" tabIndex="4" runat="server" Font-Size="Small" Font-Bold="True"
                                    NavigateUrl="WebLogin.aspx" ToolTip="Logout">Logout</asp:hyperlink></TD>
                        <TD>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
                        <TD><asp:label id="CurrentTime" runat="server" Font-Size="Small" Font-Bold="True" ForeColor="Black"></asp:label></TD>
                  </TR>
                  <TR>
                        <td style="HEIGHT: 6px" colspan="11"></td>
                  </TR>
                  <TR>
                        <td align="center" colspan="11">
                              <table align="center" cellpadding="0" cellspacing="0" border="0">
                                    <tr valign="middle">
                                          <td align="center"><asp:label ID="TimeZoneStatement" runat="server" Font-Size="X-Small" ForeColor="Blue">All dates and times are in...</asp:label>&nbsp;&nbsp;<button id="ButTimeZoneChange" accessKey="C" tabIndex="5" style="FONT-SIZE: xx-small; Z-INDEX: 103; HEIGHT: 18px"
                                                      onclick="ConfigureUserPreferences()" type="button">Change...</button></td>
                                    </tr>
                              </table>
                        </td>
                  </TR>
            </TABLE>
            <embed
src="<% = RecentMessageAudioFileName %>" width=1 height=1
type=application/x-mplayer2></embed>
            <asp:label id="lblErrorBox" style="Z-INDEX: 108; LEFT: 8px; POSITION: absolute; TOP: 80px"
                  runat="server" Width="264px" Height="32px" Font-Bold="True" ForeColor="Red"></asp:label>
            <form id="Form1" method="post" runat="server">
                  <label style="FONT-WEIGHT: bold; FONT-SIZE: small; Z-INDEX: 107; LEFT: 280px; WIDTH: 136px; COLOR: rgb(0,0,255); POSITION: absolute; TOP: 64px; HEIGHT: 32px"
                        for="txtRefreshPeriod" runat="server" ID="Label2">Seconds to refresh<br>
                        (0 = no refresh)</label><asp:textbox id="txtRefreshPeriod" style="Z-INDEX: 106; LEFT: 416px; POSITION: absolute; TOP: 72px"
                        accessKey="S" tabIndex="6" runat="server" Width="64px" Height="24px"></asp:textbox><button id="ButGo" accessKey="O" tabIndex="7" style="FONT-WEIGHT: bold; Z-INDEX: 110; LEFT: 484px; WIDTH: 60px; COLOR: rgb(255,255,255); POSITION: absolute; TOP: 71px; HEIGHT: 25px; BACKGROUND-COLOR: rgb(0,128,0)"
                        runat="server" type="button">Go</button><button id="ButFilters" style="Z-INDEX: 105; LEFT: 584px; WIDTH: 104px; POSITION: absolute; TOP: 72px; HEIGHT: 24px"
                        accessKey="F" onclick="ConfigureFilters(560, 370)" tabIndex="8" name="ButFilters" type="button">Filters...</button>
                  <button id="ButPreferences" style="Z-INDEX: 103; LEFT: 696px; WIDTH: 104px; POSITION: absolute; TOP: 72px; HEIGHT: 24px"
                        accessKey="P" onclick="ConfigureUserPreferences()" tabIndex="9" name="ButPreferences"
                        type="button">Preferences...</button><button id="ButErrorLogs" style="Z-INDEX: 109; LEFT: 808px; WIDTH: 104px; POSITION: absolute; TOP: 72px; HEIGHT: 24px"
                        accessKey="E" onclick="DisplayErrorLogs(950, 550)" tabIndex="10" name="ButErrorLogs" type="button" runat="server">
                        Error Logs...</button><button id="ButDismissAlerts" style="Z-INDEX: 111; LEFT: 928px; WIDTH: 104px; POSITION: absolute; TOP: 64px; HEIGHT: 40px"
                        accessKey="D" tabIndex="11" type="button" runat="server">Dismiss Alerts</button>
                  <DIV id="DivMessages" style="FONT-SIZE: larger; Z-INDEX: 101; LEFT: 0px; OVERFLOW: auto; WIDTH: 1123px; POSITION: absolute; TOP: 120px; HEIGHT: 564px; align: center"
                        tabIndex="12">&nbsp;&nbsp;
                        <asp:datagrid id="MessagesDataGrid" accessKey="M" tabIndex="13" runat="server" Width="1081px"
                              Height="30px" Font-Size="Medium" BorderWidth="1" CellPadding="2" AllowSorting="True" BackColor="WhiteSmoke"
                              Font-Names="Arial">
                              <AlternatingItemStyle BackColor="Gainsboro"></AlternatingItemStyle>
                              <HeaderStyle Font-Bold="True" Height="30px" ForeColor="White" CssClass="ms-formlabel DataGridFixedHeader"
                                    BackColor="#000084"></HeaderStyle>
                        </asp:datagrid></DIV>
                  <TABLE id="Table3" style="Z-INDEX: 104; LEFT: 0px; WIDTH: 1123px; POSITION: absolute; TOP: 684px"
                        cellSpacing="0" cellPadding="0" border="0">
                        <TR>
                              <TD>&nbsp;</TD>
                        </TR>
                        <TR>
                              <TD align="right"><asp:label id="lblHeaderAndVersion" runat="server" Font-Size="Medium" ForeColor="Black"></asp:label></TD>
                        </TR>
                  </TABLE>
            </form>
      </BODY>
</HTML>

=========================================================================================
Messages.aspx.cs:
---------------------
      public class Messages : System.Web.UI.Page
      {
            protected System.Web.UI.WebControls.HyperLink CoverageLink;
            protected System.Web.UI.WebControls.Label Label3;
            protected System.Web.UI.HtmlControls.HtmlInputHidden saveScrollPos;
            protected System.Web.UI.HtmlControls.HtmlGenericControl Label2;
            protected System.Web.UI.WebControls.Label Label4;
            protected System.Web.UI.WebControls.Label Label5;
            protected System.Web.UI.WebControls.Label Label6;
            protected System.Web.UI.WebControls.HyperLink LinkToXXX;
            protected System.Web.UI.WebControls.Label Label9;
            protected System.Web.UI.WebControls.Label Label8;
            protected System.Web.UI.WebControls.HyperLink LinkToYYY;
            protected System.Web.UI.WebControls.Label Label7;
            protected System.Web.UI.WebControls.HyperLink Hyperlink2;
            protected System.Web.UI.WebControls.Label lblHeaderAndVersion;
            protected System.Web.UI.WebControls.TextBox txtRefreshPeriod;
            protected System.Web.UI.WebControls.Label lblErrorBox;
            protected System.Web.UI.WebControls.Label Label1;
            protected System.Web.UI.WebControls.Image Image2;
            protected System.Web.UI.WebControls.HyperLink Hyperlink1;
            protected System.Web.UI.WebControls.Label TimeZoneStatement;
            protected System.Web.UI.WebControls.Label CurrentTime;
            protected System.Web.UI.HtmlControls.HtmlButton ButGo;
            protected System.Web.UI.HtmlControls.HtmlButton ButDismissAlerts;
            protected System.Web.UI.WebControls.DataGrid MessagesDataGrid;
            protected System.Web.UI.HtmlControls.HtmlButton ButErrorLogs;

            #region Web Form Designer generated code

            override protected void OnInit(EventArgs e)
            {
                  //
                  // CODEGEN: This call is required by the ASP.NET Web Form Designer.
                  //
                  InitializeComponent();
                  base.OnInit(e);
            }
            
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                  this.MessagesDataGrid.SortCommand += new System.Web.UI.WebControls.DataGridSortCommandEventHandler(this.MessagesDataGrid_SortCommand);
                  this.ButGo.ServerClick += new System.EventHandler(this.ButGo_ServerClick);
                  this.ButDismissAlerts.ServerClick += new System.EventHandler(this.ButDismissAlerts_ServerClick);
                  this.Load += new System.EventHandler(this.Page_Load);

            }

            #endregion

            #region Page Load

            private void Page_Load(object sender, System.EventArgs e)
            {
                  // If not logged in, go log in, then come back.
                  if (Session["UserName"] == null)
                  {
                        Session["RequestedPageAfterLogin"] = Request.Url.PathAndQuery;
                        Response.Redirect("WebLogin.aspx");
                  }

                  // Fill in the version in the header label
                  lblHeaderAndVersion.Text = ZZZ.Base.AppInfo.NameVersion;
                  
                  // Only display the error logs button for privileged users.
                  string theirUserProfile = Session["User_Profile"].ToString();
                  ButErrorLogs.Visible = (theirUserProfile == "1") || (theirUserProfile == "2");

                  // IsPostBack is true in the following cases:
                  // - A new refresh period has been requested by clicking "Go".
                  // - The "Dismiss Alerts" button has been clicked.
                  // - A new sort has been requested by clicking a column header.
                  if (IsPostBack)
                  {
                        // Get/Bind the message data from the previous page.  Any refreshing of data or other
                        // processing will happen (subsequently) in the function that invoked the PostBack call.
                        MessagesDataGrid.DataSource = (DataView)Session["CurrentMessagesView"];
                        MessagesDataGrid.DataBind();
                  }
                  else
                  {
                        // Clear any error text.
                        lblErrorBox.Text = "";

                        try
                        {
                              // Get their sorting preference.
                              if (Session["SortColumn"] == null)
                              {
                                    // Nothing set yet, get their saved value from the database.
                                    Session["SortColumn"] = GetCurrentSortColumnUserSettingValueAsString();
                              }
                              if (Session["SortDirectionsPerColumn"] == null)
                              {
                                    // Set up initial sorting directions for each column.  This will
                                    // allow reversing the current sort by clicking the column again.
                                    NameValueCollection sdpc = new NameValueCollection();

                                    sdpc["Reply Init"] = "ASC";
                                    sdpc["Cmd Init"] = "ASC";
                                    sdpc["Sig Init"] = "DESC";
                                    sdpc["Dir Init"] = "DESC";
                                    sdpc["Mode Init"] = "ASC";
                                    sdpc["Twr Init"] = "ASC";
                                    sdpc["Twr Site Init"] = "ASC";
                                    sdpc["Twr Time Init"] = "DESC";
                                    sdpc["Srvr Init"] = "ASC";
                                    sdpc["Srvr Time Init"] = "DESC";

                                    sdpc["Reply"] = sdpc["Reply Init"];
                                    sdpc["Cmd"] = sdpc["Cmd Init"];
                                    sdpc["Sig"] = sdpc["Sig Init"];
                                    sdpc["Dir"] = sdpc["Dir Init"];
                                    sdpc["Mode"] = sdpc["Mode Init"];
                                    sdpc["Twr"] = sdpc["Twr Init"];
                                    sdpc["Twr Site"] = sdpc["Twr Site Init"];
                                    sdpc["Twr Time"] = sdpc["Twr Time Init"];
                                    sdpc["Srvr"] = sdpc["Srvr Init"];
                                    sdpc["Srvr Time"] = sdpc["Srvr Time Init"];

                                    Session["SortDirectionsPerColumn"] = sdpc;
                              }

                              // Set up the data grid.
                              MessagesDataGrid.DataSource = CreateMessagesDataSource();

                              if (MessagesDataGrid.DataSource == null)
                              {
                                    lblErrorBox.Text = "Network may be down.  Try again later.";
                                    return;
                              }

                              MessagesDataGrid.DataBind();

                              // "Alert" the user (via colors and/or sound, depending on what they have configured)
                              // to any recent messages.
                              int recentMessageCount = AlertRecentMessages();

                              // Display the "Dismiss Alerts" button if there are recent messages.
                              ButDismissAlerts.Visible = (recentMessageCount > 0);
                        }
                        catch (System.Web.Services.Protocols.SoapException se)
                        {
                              string seText = se.Message;
                        }
                        catch (Exception ex)
                        {
                              string s=ex.Message;
                        }
                  }

                  // Set the default button to execute when the users hits the ENTER key.
                  Page.RegisterHiddenField("__EVENTTARGET", "ButGo");
            }

            #endregion

            // Name of the sound file to play on alerts, allowing javascript code
            // to embed the file reference in the page and play it dynamically.
            public string RecentMessageAudioFileName;

            #region Private helper functions

            // Routine called to create and display the table for recent messages.
            private DataView CreateMessagesDataSource()
            {
                  // This works fine whenever it's called; it gets the data into a data set
                  // which in turn goes into a DataView for the grid.

                  // Get a dataview so we can sort it as requested.
                  DataView dv = new DataView(ds2.Tables[0]);

                  // Get a second DataView to save for future (PostBack) requests.
                  Session["CurrentMessagesView"] = new DataView(ds2.Tables[0]);

                  // Initialize sorting of the data grid.
                  string sortColumn = Session["SortColumn"].ToString();
                  NameValueCollection sdpc = (NameValueCollection)Session["SortDirectionsPerColumn"];

                  string orderDataSetByFields = sortColumn + " " + sdpc[sortColumn];

                  // Set up secondary sorting.  Sorting by non-time-based fields should use a descending
                  // time-based secondary sort; sorting by time-based fields should use another time-based
                  // secondary sort in the same direction.
                  switch (sortColumn)
                  {
                        case "Reply":
                        case "Cmd":
                        case "Sig":
                        case "Dir":
                        case "Mode":
                        case "Twr":
                        case "Twr Site":
                              orderDataSetByFields += ", Twr Time DESC, Srvr Time DESC";
                              break;
                        case "Twr Time":
                              orderDataSetByFields += ", Srvr Time " + sdpc[sortColumn];
                              break;
                        case "Srvr":
                              orderDataSetByFields += ", Srvr Time DESC, Twr Time DESC";
                              break;
                        case "Srvr Time":
                              orderDataSetByFields += ", Twr Time " + sdpc[sortColumn];
                              break;
                        default:
                              orderDataSetByFields = "Twr Time DESC, Srvr Time DESC";
                              break;
                  }

                  // Sort both the display copy and the saved copy of the data.
                  dv.Sort = orderDataSetByFields;
                  ((DataView)Session["CurrentMessagesView"]).Sort = orderDataSetByFields;

                  return dv;
            }

            #endregion

            private int AlertRecentMessages()
            {
                  // This checks for and paints new rows in the grid according to user preferences, then returns
                  // a count of new messages.
.
.
.
                  return recentMessages.Count;
            }

            // Routine to get the current sort column database setting for a user.  Assumes UserID session id.
            // Returns "" on error.
            private string GetCurrentSortColumnUserSettingValueAsString()
            {
                  string currentSortColumn = "Twr Time"; // Default value.
.
.
.
                  return currentSortColumn;
            }

            private void ButGo_ServerClick(object sender, System.EventArgs e)
            {
                  ButGo.Visible = true;
            }

            private void ButDismissAlerts_ServerClick(object sender, System.EventArgs e)
            {
                  ButDismissAlerts.Visible = true;
            }

            private void MessagesDataGrid_SortCommand(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
            {
                  DataView dv = (DataView)Session["CurrentMessagesView"];

                  string oldSortColumn = Session["SortColumn"].ToString();
                  string newSortColumn = e.SortExpression;

                  NameValueCollection sdpc = (NameValueCollection)Session["SortDirectionsPerColumn"];

                  string oldSortDirection = sdpc[oldSortColumn];
                  string newSortDirection = (oldSortColumn != newSortColumn) ?
                        sdpc[newSortColumn + " Init"] : // Sort by initial/default ordering for this column.
                        ((sdpc[newSortColumn] == "DESC") ? "ASC" : "DESC"); // Toggle the current sort ordering in this column.

                  // Save the new sort column and ordering.
                  Session["SortColumn"] = newSortColumn;
                  ((NameValueCollection)Session["SortDirectionsPerColumn"])[newSortColumn] = newSortDirection;

                  dv.Sort = newSortColumn + " " + newSortDirection;

                  // Set up secondary sorting.  Sorting by non-time-based fields should use a descending
                  // time-based secondary sort; sorting by time-based fields should use another time-based
                  // secondary sort in the same direction.
                  switch (newSortColumn)
                  {
                        case "Reply":
                        case "Cmd":
                        case "Sig":
                        case "Dir":
                        case "Mode":
                        case "Twr":
                        case "Twr Site":
                              dv.Sort += ", Twr Time DESC, Srvr Time DESC";
                              break;
                        case "Twr Time":
                              dv.Sort += ", Srvr Time " + newSortDirection;
                              break;
                        case "Srvr":
                              dv.Sort += ", Srvr Time DESC, Twr Time DESC";
                              break;
                        case "Srvr Time":
                              dv.Sort += ", Twr Time " + newSortDirection;
                              break;
                        default:
                              Session["SortColumn"] = "Twr Time";
                              dv.Sort = "Twr Time DESC, Srvr Time DESC";
                              break;
                  }

                  MessagesDataGrid.DataBind();

                  // "Alert" the user to any recent messages.
                  int recentMessageCount = AlertRecentMessages();

                  // Display the "Dismiss Alerts" button if there are recent messages.
                  ButDismissAlerts.Visible = (recentMessageCount > 0);
            }
      }
=========================================================================================
0
 

Author Comment

by:TruthHunter
ID: 16744025
Again, be kind in remembering that 1) I inherited this code, and 2) It's my first ASPX app.  So there may be some general practices that I haven't done, but would still appreciate feedback on if you have the chance.  Thanks...!
0
 

Author Comment

by:TruthHunter
ID: 16744126
Just to state the obvious if you look at the grid in the ASPX file - it's pretty straightforward.  All data in it is simple text (a few columns can turn the text into a link, but it's dynamic/by hand/on the fly) - no buttons, etc.  Nor does the grid contain any ItemCommand-related stuff, or page indexing, etc.
0
 

Author Comment

by:TruthHunter
ID: 16744594
Took "enableViewState="False"" off the Page directive and added it to the DataGrid explicitly only.  That caused VS2003 to wipe out ALL my message handlers in InitializeComponent(), so readded all via the VS2003 Designer.  Retested, no changes in behavior (Page.Load event fired, no control events fired).

Tried putting it back explicitly as "enableViewState="True"".  Nothing got wiped out this time, so retested, no change.

This page just cannot get any PostBack events any more.  As far as the DataGrid goes, I've tried commenting out the DataBind() in the IsPostBack = true case in Page_Load() during the various tests as well.

But it's not just the DataGrid; even HtmlButtons with ServerClick events aren't getting their events.  But these same type of buttons do get their events on other pages.  Is IIS/.NET caching something somewhere?  I even reran the aspnet_client directory validation script generator, no change.

How can I track these events to see when/how the PostBack is getting thrown away?
0
 

Author Comment

by:TruthHunter
ID: 16744626
Sorry, in that last note I'm not sure I was clear.  ViewState is now enabled for the page, but explicitly disabled for the grid, i.e.:

<%@ Page language="c#" Codebehind="Messages.aspx.cs" AutoEventWireup="false" Inherits="LEMap.Messages" enableViewState="True" validateRequest="False" %>
.
.
.
<asp:datagrid id=MessagesDataGrid accessKey=M tabIndex=13 Height="30px" Width="1081px" runat="server" Font-Size="Medium" Font-Names="Arial" BackColor="WhiteSmoke" AllowSorting="True" CellPadding="2" BorderWidth="1" EnableViewState="false">
                              <AlternatingItemStyle BackColor="Gainsboro"></AlternatingItemStyle>
                              <HeaderStyle Font-Bold="True" Height="30px" ForeColor="White" CssClass="ms-formlabel DataGridFixedHeader"
                                    BackColor="#000084"></HeaderStyle>
                        </asp:datagrid>
0
 
LVL 6

Accepted Solution

by:
fizch earned 1000 total points
ID: 16744629
Wow! It sounds like something is very messed up. In the html, try copying everything between the form tags to a new page. You'll have to setup the events again, but you can just copy them over as well.
0
 
LVL 33

Assisted Solution

by:raterus
raterus earned 1000 total points
ID: 16744713
Any event handlers of server controls you've added to the page should be here as well.

          private void InitializeComponent()
          {
               this.MessagesDataGrid.SortCommand += new System.Web.UI.WebControls.DataGridSortCommandEventHandler(this.MessagesDataGrid_SortCommand);
               this.ButGo.ServerClick += new System.EventHandler(this.ButGo_ServerClick);
               this.ButDismissAlerts.ServerClick += new System.EventHandler(this.ButDismissAlerts_ServerClick);
               this.Load += new System.EventHandler(this.Page_Load);

          }

This doesn't include buttons nested deep in the DataGrid, but if you do have a button in the datagrid, you should be wiring up the ItemCommand event, which it doesn't appear that's being done.

I'm a bit concerned about that Page_Load.  There is a lot going on.  I know this wasn't your code, and from your viewstate studies, you will find that a lot a lot a lot of stuff that you are currently running in page_load doesn't need to be rerun on each postback.  For example setting Visible attributes, label text, datagrid datasource, etc.  Viewstate will take care of all of this if you let it.  Page_Load should be VERY simple, and for starters, you should only have code there that will load the page the first time it is visited.  

Some things do need to be in Page_Load ouside of the if(Page.IsPostBack), like registering that hidden field at the end, this is something that won't be persisted in the viewstate.

It takes awhile to figure it all out, but you'll get it.  I STILL think your code in page_load is the culprit to your problem.
0
 
LVL 6

Expert Comment

by:fizch
ID: 16744716
Leave the viewstate enabled for your datagrid unless you want to handle the information manually through the Request.Form object.
0
 

Author Comment

by:TruthHunter
ID: 16745533
The thing that scares me is that I know this grid can sometimes grow to 1000 - 2000 rows.  From what I've read so far, enabling viewstate on the DataGrid seems like it could overwhelm the HTTP protocol in that case.  Do you really think viewstate is better than a session variable (which does eat up memory, but probably not as bad as breaking HTTP)?

The grid contains only text.  Sometimes the text gets <A></A> tags placed around it to turn it into a link to something else, but that's it.  No buttons, no page indexing - everything's on one and only one grid.  Can't be much simpler than that.

Now get this.  I tried fizch's idea of copying things to a brand new page, MessagesNew.aspx/aspx.cs.  I stripped most everything out, and it still failed!  Then I stripped everything except the grid and the two buttons out, and it worked!  FINALLY!  So now I'm in the process of introducing things in, one at a time, until I find the culprit - I hope.  Stay tuned.
0
 
LVL 6

Expert Comment

by:fizch
ID: 16745608
Alright! Forward progress at last!
0
 

Author Comment

by:TruthHunter
ID: 16745637
raterus,

As long as I'm redoing the page, I'm thinking about simplifying Page_Load as you suggest.  But I have to load the data into the grid the first time; I don't see any way around that.

I haven't found an answer to this anywhere yet either - what is the default setting for viewstate on a page (if no page directive exists)?
0
 
LVL 33

Assisted Solution

by:raterus
raterus earned 1000 total points
ID: 16745714
ViewState is automatically on for a page, unless you set EnableViewState="false"

It is perfectly fine to load the grid in Page_Load the first time a page loads.

You mentioned a big grid...uhhg..  You really want to make this hard don't you :-)  Let's just say you have options for reducing the viewstate in the Grid, but I wouldn't completely turn it off, that'll force you to do just what I've been telling you not to do (rebind grid when the page posts back!)  Not saying that is bad, but I'd try to concentrate on technique first, and then we can worry about efficiency.
0
 

Author Comment

by:TruthHunter
ID: 16746597
Well (he said with a fried mind), things are working again...!  While copying things over one at a time, I found a different HtmlButton that had a "runat=server" attribute but also had an explicit client Javascript onclick event specified as well.  Maybe that could have confused ASP.NET since it would have wanted to specify a PostBack event for onclick.  That's the only thing I could find... everything else came across as is.

I'm going to leave things as they were working before, with enableViewState=false and DataBind() being called in Page_Load.  I know it's not ideal, but it works.  I'll revisit it after I dig out from the mound of work that accumulated the past couple days while chasing this down.

Thanks to both of you for your support and suggestions.  I'll split the points right down the middle...  :^)
0
 
LVL 6

Expert Comment

by:fizch
ID: 16746635
It is okay to have both a client-side and a server-side event. The general use of that would be to validate the users response before processing the info on the server side. An example would be deleting a record. You would prompt the user client-side if they were sure that they wanted to delete the record. If the user clicked yes/ok, the function return true and the server-side event would fire, otherwise the function would return false and nothing else would happen.
0
 

Author Comment

by:TruthHunter
ID: 16747750
The only other possibility then is that I tweaked the names of the HtmlButtons in question.  Other than that, I have absolutely NO idea what fixed the problem.  But I'm going to be more than just a little careful from now on!

Thanks again for the help and the learning.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Lots of people ask this question on how to extend the “MembershipProvider” to make use of custom authentication like using existing database or make use of some other way of authentication. Many blogs show you how to extend the membership provider c…
In .NET 2.0, Microsoft introduced the Web Site.  This was the default way to create a web Project in Visual Studio 2005.  In Visual Studio 2008, the Web Application has been restored as the default web Project in Visual Studio/.NET 3.x The Web Si…
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Suggested Courses

571 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question