Friday, March 16, 2012

NewPageIndex Doesn't Get Updated in PageIndexChanging Event

We have a base class that is responsible for creating the navigation and loo
k
and feel of our applications. So all our web pages inherit from this base
page so they don't have to worry about the look and feel and navigation, onl
y
the main content. Everything has woked just fine until we converted to 2.0.
Now we have a problem with the new GridView and the paging. With the
DataGrid in 1.1, the paging worked just fine. Now with paging turned on and
the mode set to "NextPrevious" the NewPageIndex doesn't get updated in the
PageIndexChanging event. However if I change the web page to not inherit
from my base class but just from the System.web.ui.page then the paging work
s
correctly. This is a code snipit of our base class and how it loads the
controls from the derived page. I am really stumped on this one so if anyon
e
has any ideas it would be greatly appreciated.
ASPX Page:
<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" %>
<asp:GridView ID="GridView1" runat="server" AllowPaging="true"
OnPageIndexChanging="GridView1_PageIndexChanging">
<PagerSettings Mode="NextPrevious"></PagerSettings>
</asp:GridView>
Code Behind (scaled down and only showing the basics):
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.OleDb;
public partial class _Default : MyBasePage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GridView1.DataSource = GetDataSource();
GridView1.DataBind();
}
}
protected void GridView1_PageIndexChanging(object sender,
GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
GridView1.DataSource = GetDataSource();
GridView1.DataBind();
}
private DataSet GetDataSource()
{
OleDbConnection cn = new
OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Ole DB Services=-4; Data
Source=C:\\Program Files\\Microsoft Visual Studio\\VB98\\nwind.mdb");
OleDbDataAdapter da = new OleDbDataAdapter("Select CompanyName,
ContactName, Address from Customers", cn);
DataSet customers = new DataSet();
da.Fill(customers, "Customers");
return customers;
}
}
public class MyBasePage : System.Web.UI.Page
{
HtmlForm objForm;
public MyBasePage()
{
objForm = new HtmlForm();
}
protected override void OnInit(System.EventArgs e)
{
BuildPage();
base.OnInit(e);
}
private void BuildPage()
{
for (int i = 0; i < this.Controls.Count; i++)
{
System.Web.UI.Control objCtrl = this.Controls[0];
objForm.Controls.Add(objCtrl);
this.Controls.Remove(objCtrl);
}
this.Controls.Add(objForm);
}
}Hi,
Thank you for your post.
First, this problem can be fixed by using following BuildPage() function:
private void BuildPage()
{
ArrayList al = new ArrayList();
foreach(Control c in Controls)
{
al.Add(c);
}
Controls.Add(objForm);
foreach(Control c in al)
{
objForm.Controls.Add(c);
}
}
Following are detailed causes:
1) The root cause of this problem is GridView's PageIndex is stored using
ASP.NET 2.0's new feature called "ControlState". See following MSDN for
more info:
http://msdn2.microsoft.com/en-us/li...atepersister.co
ntrolstate.aspx
A server control that use control state must call the
RegisterRequiresControlState method on each request because registration
for control state is not carried over from request to request during a
postback event. It is recommended that registration occur in the Init event.
GridView calls this method in its OnInit:
protected internal override void OnInit(EventArgs e)
{
base.OnInit(e);
if (this.Page != null)
{
if ((this.DataKeyNames.Length > 0) &&
!this.AutoGenerateColumns)
{
this.Page.RegisterRequiresViewStateEncryption();
}
this.Page.RegisterRequiresControlState(this);
}
}
Please note that it checks for "this.Page != null" first.
2) When adding a control to a ControlCollection, it will automatically
first remove it from its old parent.Controls (if its parent is not null),
and removing a control will Unload it first!
In previous code, when we first add the GridView to objForm.Controls,
because objForm is not added to Page.Controls yet, the "this.Page != null"
will be false for the GridView, thus not calling the
RegisterRequiresControlState.
So, what we are doing now is first adding the objForm to Page.Controls,
then add the remaining controls to objForm, this will ensure GridView's
ControlState is persisted.
As a side note, in ASP.NET 2.0, we have a new feature called MasterPage
which is exactly for the purpose of keeping a consistent look and feel for
the entire website.
Hope this helps. Please feel free to post here if anything is unclear.
Regards,
Walter Wang
Microsoft Online Community Support
========================================
==========
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
========================================
==========
This posting is provided "AS IS" with no warranties, and confers no rights.
Walter, thanks for the reply. That fixed it. However, this brings up
another question. We currently use this base page for our 1.1 apps. We hav
e
some groups in our company that are trying to use our base page compiled wit
h
1.1 in their 2.0 web apps. This is the first issue we have ran into with
trying to use our 1.1 base code in a 2.0 app. If I go change our base page
to load the form into the page object before I load any controls into the
form collection, will this cause any problems with any of the 1.1 controls?
Also, in response to your side note, I wanted to use the Master pages but
unfortunately our base page is in a class library in a seperate assembly
rather than in the web application itself so there was no way to use the
master pages. At least this is what Microsoft told us. We distribute this
assembly throughout our company to let other development teams use in order
to have the corporate look and feel.
"Walter Wang [MSFT]" wrote:

> Hi,
> Thank you for your post.
> First, this problem can be fixed by using following BuildPage() function:
> private void BuildPage()
> {
> ArrayList al = new ArrayList();
> foreach(Control c in Controls)
> {
> al.Add(c);
> }
> Controls.Add(objForm);
> foreach(Control c in al)
> {
> objForm.Controls.Add(c);
> }
> }
> Following are detailed causes:
> 1) The root cause of this problem is GridView's PageIndex is stored using
> ASP.NET 2.0's new feature called "ControlState". See following MSDN for
> more info:
> [url]http://msdn2.microsoft.com/en-us/library/system.web.ui.pagestatepersister.co[/ur
l]
> ntrolstate.aspx
> A server control that use control state must call the
> RegisterRequiresControlState method on each request because registration
> for control state is not carried over from request to request during a
> postback event. It is recommended that registration occur in the Init even
t.
> GridView calls this method in its OnInit:
> protected internal override void OnInit(EventArgs e)
> {
> base.OnInit(e);
> if (this.Page != null)
> {
> if ((this.DataKeyNames.Length > 0) &&
> !this.AutoGenerateColumns)
> {
> this.Page.RegisterRequiresViewStateEncryption();
> }
> this.Page.RegisterRequiresControlState(this);
> }
> }
> Please note that it checks for "this.Page != null" first.
> 2) When adding a control to a ControlCollection, it will automatically
> first remove it from its old parent.Controls (if its parent is not null),
> and removing a control will Unload it first!
> In previous code, when we first add the GridView to objForm.Controls,
> because objForm is not added to Page.Controls yet, the "this.Page != null"
> will be false for the GridView, thus not calling the
> RegisterRequiresControlState.
> So, what we are doing now is first adding the objForm to Page.Controls,
> then add the remaining controls to objForm, this will ensure GridView's
> ControlState is persisted.
> As a side note, in ASP.NET 2.0, we have a new feature called MasterPage
> which is exactly for the purpose of keeping a consistent look and feel for
> the entire website.
> Hope this helps. Please feel free to post here if anything is unclear.
> Regards,
> Walter Wang
> Microsoft Online Community Support
> ========================================
==========
> When responding to posts, please "Reply to Group" via your newsreader so
> that others may learn and benefit from your issue.
> ========================================
==========
> This posting is provided "AS IS" with no warranties, and confers no rights
.
>

0 comments:

Post a Comment