Problem with paging in datagrid

M

Martin Bischoff

Hi,

I have a datagrid, which I bind to an array of objects stored in the
session. I'm using numeric paging on the datagrid, which works fine
until the number of pages is higher than PageButtonCount.


This is what happens, when I have 30 pages and PageButtonCount is set to 10:

- Paging works as expected as long as I click page 1..10.
- clicking the ellipsis link, correctly displays page 11 and links to
pages 11 to 20.
- If I now click on the link for page 12, the grid will display page 3
instead. If I set a breakpoint in PageIndexChanged, I can see that
e.NewPageIndex is 2.

Please see below for a code sample.

What am I doing wrong? How can this problem be fixed?

Thanks for any help,
Martin


Here are the relevant code extracts:

ASPX:
-----------------------------
<asp:Label id=Label1 runat="server">Label</asp:Label>
<asp:DataGrid id=DataGrid1
style="Z-INDEX: 102; LEFT: 16px; POSITION: absolute; TOP: 40px"
runat="server"
AutoGenerateColumns="False" AllowPaging="True">
<columns>
<asp:BoundColumn DataField="ProductID"></asp:BoundColumn>
<asp:BoundColumn DataField="message"></asp:BoundColumn>
</Columns>
<pagerstyle position="TopAndBottom" mode="NumericPages">
</PagerStyle>
</asp:DataGrid>
-----------------------------

Codebehind (ASPX.CS):
-----------------------------
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.DataGrid DataGrid1;

DataTable LoadDataSource()
{
DataTable dt = new DataTable();
dt.Columns.Add("ProductID", typeof(int));
dt.Columns.Add("message", typeof(string));

DataRow dr;
for(int idx=0;idx< 300;idx++)
{
dr = dt.NewRow();
dr[0] = idx;
dr[1] = "Message " + idx.ToString();
dt.Rows.Add(dr);
}
return dt;
}

private void Page_Load(object sender, System.EventArgs e)
{
DataGrid1.DataSource = LoadDataSource();
DataGrid1.DataBind();
DataGrid1.EnableViewState = false;
}

private void DataGrid1_PageIndexChanged(object source,
System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
{
DataGrid1.CurrentPageIndex = e.NewPageIndex;
Label1.Text = e.NewPageIndex.ToString();
DataGrid1.DataSource = LoadDataSource();
DataGrid1.DataBind();
}
-----------------------------
 
J

Jeffrey Tan[MSFT]

Hi Martin,

After trying your code, I reproduced out your problem.

The problem is due to this sentence:
DataGrid1.EnableViewState = false;

Because you disabled the datagrid's viewstate, it can not perist its state
between every 10 buttons postback.

The solution is simple, just remove this sentence.

Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
M

Martin Bischoff

Hi Jeffrey,

thanks a lot for your quick answer. I knew that enabling the viewstate
"solves" the problem, but I'd like to disable the viewstate to decrease
the size of the page and postback.
Is there any way the solve the problem without enabling the viewstate?

Best regards,
Martin
 
J

Jeffrey Tan[MSFT]

Hi Martin,

Thanks for your feedback.

I see your concern. But viewstate is the place for Asp.net WebForm to store
and persist state, if you disabled the viewstate the datagrid's state is
hard to pesist between postback(In our situation, postback is the page
number link click).

To persist the page number without viewstate between postback, we need find
a place to store some information, session is a good place for this. Also,
because of the disabling of viewstate, DataGrid's build-in PageIndexChanged
event will be not suitable for retrieving page number, we have to give it
up, but handle all the things ourself.

Below is the sample code I wrote to workaround this issue:
DataTable LoadDataSource()
{
DataTable dt = new DataTable();
dt.Columns.Add("ProductID", typeof(int));
dt.Columns.Add("message", typeof(string));

DataRow dr;
for(int idx=0;idx< 300;idx++)
{
dr = dt.NewRow();
dr[0] = idx;
dr[1] = "Message " + idx.ToString();
dt.Rows.Add(dr);
}
return dt;
}

private int pagenum=0;
private void Page_Load(object sender, System.EventArgs e)
{
if(!this.IsPostBack)
{
this.Session["pagenum"]=0;
}

if(this.Session["pagenum"]!=null)
{
this.pagenum=(int)this.Session["pagenum"];
}


if(this.Request.Form["__EVENTTARGET"]!=null&&this.Request.Form["__EVENTTARGE
T"].StartsWith("DataGrid1:_ctl14:_ctl"))
{
string sub_str=this.Request.Form["__EVENTTARGET"].Substring(21);
int link_num=Int32.Parse(sub_str);

if((this.pagenum!=0)&&(link_num==0))
{
this.Session["pagenum"]=this.pagenum-1;
}
else
{
if((link_num==11)||(this.pagenum==0&&link_num==10))
{
this.Session["pagenum"]=this.pagenum+1;
}
}

if(this.pagenum==0)
{
this.DataGrid1.CurrentPageIndex=link_num;
}
else
{
this.DataGrid1.CurrentPageIndex=this.pagenum*10+link_num-1;
}

}



DataGrid1.DataSource = LoadDataSource();
DataGrid1.DataBind();
DataGrid1.EnableViewState = false;
}

Note: the main point of my sample code is the algorithm to calculate the
correct page number.

It works well on my side.
======================================
Please apply my suggestion above and let me know if it helps resolve your
problem.

Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
M

Martin Bischoff

Hi Jeffrey,
your solution works for me. I have made a small modification, to store
the current page index in the page's ViewState instead of the session
(by using this.ViewState instead of this.Session).

Thanks a lot for your help.

Best regards,
Martin Bischoff

Hi Martin,

Thanks for your feedback.

I see your concern. But viewstate is the place for Asp.net WebForm to store
and persist state, if you disabled the viewstate the datagrid's state is
hard to pesist between postback(In our situation, postback is the page
number link click).

To persist the page number without viewstate between postback, we need find
a place to store some information, session is a good place for this. Also,
because of the disabling of viewstate, DataGrid's build-in PageIndexChanged
event will be not suitable for retrieving page number, we have to give it
up, but handle all the things ourself.

Below is the sample code I wrote to workaround this issue:
DataTable LoadDataSource()
{
DataTable dt = new DataTable();
dt.Columns.Add("ProductID", typeof(int));
dt.Columns.Add("message", typeof(string));

DataRow dr;
for(int idx=0;idx< 300;idx++)
{
dr = dt.NewRow();
dr[0] = idx;
dr[1] = "Message " + idx.ToString();
dt.Rows.Add(dr);
}
return dt;
}

private int pagenum=0;
private void Page_Load(object sender, System.EventArgs e)
{
if(!this.IsPostBack)
{
this.Session["pagenum"]=0;
}

if(this.Session["pagenum"]!=null)
{
this.pagenum=(int)this.Session["pagenum"];
}


if(this.Request.Form["__EVENTTARGET"]!=null&&this.Request.Form["__EVENTTARGE
T"].StartsWith("DataGrid1:_ctl14:_ctl"))
{
string sub_str=this.Request.Form["__EVENTTARGET"].Substring(21);
int link_num=Int32.Parse(sub_str);

if((this.pagenum!=0)&&(link_num==0))
{
this.Session["pagenum"]=this.pagenum-1;
}
else
{
if((link_num==11)||(this.pagenum==0&&link_num==10))
{
this.Session["pagenum"]=this.pagenum+1;
}
}

if(this.pagenum==0)
{
this.DataGrid1.CurrentPageIndex=link_num;
}
else
{
this.DataGrid1.CurrentPageIndex=this.pagenum*10+link_num-1;
}

}



DataGrid1.DataSource = LoadDataSource();
DataGrid1.DataBind();
DataGrid1.EnableViewState = false;
}

Note: the main point of my sample code is the algorithm to calculate the
correct page number.

It works well on my side.
======================================
Please apply my suggestion above and let me know if it helps resolve your
problem.

Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Martin,

Thanks for your feedback.

I am glad my reply can help you. Yes, you can also store the information in
page's viewstate, it is another way of storing information. Actually, I
suspect you also do not want the page's viewstate, so I store the
information in session. There are also other options for storing
information, such as cookie, file I/O, Web Service etc, but others may have
performance issue, just for your information.

Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top