Hi,
I have a web site that uses user controls to display different formats of
timesheets.
I have a browse page that has prev/next buttons to browse through a set of
timesheets.
As I say they can be different user controls for each timesheet type.
The problem is when I navigate (prev/next) from one type of user control to
the next type
I get this error
System.Web.HttpException: Failed to load viewstate. The control tree into
which viewstate is being loaded must match the control tree that was used to
save viewstate during the previous request. For example, when adding
controls dynamically, the controls added during a post-back must match the
type and position of the controls added during the initial request.
The thing is strange is that say the first user control is for monthly
timesheets and then I click next to goto
a weekly timesheet (different user control) it is fine. But when i go back
to the first monthly timsheet
again it gives this error.
Help!!
rotsey
bruce barker - 04 Dec 2007 06:33 GMT
when viewstate is loaded after a postback, it looks for controls with
the same name and type to load.
if you dynamically change the user control you can get this error. you
should keep track of which control you rendered (say a flag in
viewstate) and recreate the control in oninit. then in onload/prerender
if you change the control, delete the old one and add the new one.
-- bruce (sqlwork.com)
> Hi,
>
[quoted text clipped - 24 lines]
> Help!!
> rotsey
SMiGL - 04 Dec 2007 09:31 GMT
On Dec 4, 4:31 am, "Rotsey" <malcolm_sm...@RemoveThis.optusnet.com.au>
wrote:
> Hi,
>
[quoted text clipped - 24 lines]
> Help!!
> rotsey
This problem arise when you dynamic create child control and for this
create use some variable. After postback this variable has old value
that give at Initialize method. To fix this problem need recover this
varible, for this use SaveControlState, LoadControlState.
Example
public class UniversalFilterControl1 : WebControl
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.RegisterRequiresControlState(this);
}
protected override void LoadControlState(object savedState)
{
object[] list = savedState as object[];
base.LoadControlState(list[0]);
if (list[1] != null)
<some varible> = list[1];
}
protected override object SaveControlState()
{
object[] list = new object[2];
list[0] = base.SaveControlState();
list[1] = <some varible>;
}
}
Rotsey - 04 Dec 2007 23:39 GMT
This was working fine before I made some styling changes to the page.
Can you please take a look at this code and offer suggestins how to alter
it???
I added a OnInit and got a stackoverflow exception.
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If Not Me.Request.Params("Browse") Is Nothing Then
lstType = CInt(Me.Request.Params("Browse"))
Else
lstType = EnumListType.TimesheetAwaiting
Session("EmployeeID") = 1
End If
If Not IsPostBack Then
GetDocumentList()
Session("DocIndex") = 0
End If
BuildPage()
LoadDocument()
If Not IsPostBack Then
'GetDocumentList()
'Session("DocIndex") = 0
End If
End Sub
Public Sub BuildPage()
Dim tbl As New Table
Dim r As New TableRow
Dim c As TableCell
tbl.Width = Unit.Pixel(660)
tbl.Rows.Add(r)
c = New TableCell
If InStr(GetTypeDescription(lstType), "Awaiting Authorisation") Then
c.Controls.Add(New LiteralControl("<H4>" + GetTypeDescription(lstType) + "
(" + CType(Session("DocCount"), String) + ")</H4>"))
Else
c.Controls.Add(New LiteralControl("<H3>" + GetTypeDescription(lstType) + "
(" + CType(Session("DocCount"), String) + ")</H3>"))
End If
c.ColumnSpan = "2"
r.Cells.Add(c)
c = New TableCell
c.HorizontalAlign = HorizontalAlign.Right
Dim lnk As New HyperLink
lnk.Text = "<Printable Version>"
lnk.NavigateUrl = "#"
'lnk.ForeColor = Color.Blue
lnk.Attributes("onclick") = "new_window('" &
Page.ResolveUrl("~/frmPrintDocument.aspx") & "');"
c.Controls.Add(lnk)
c.Controls.Add(New LiteralControl(" "))
c.Controls.Add(NewHyperLink("frmUserHome.aspx", "<Back to Home>", ""))
r.Cells.Add(c)
ContentArea.Controls.Add(New LiteralControl("<br><center>"))
ContentArea.Controls.Add(tbl)
ContentArea.Controls.Add(New LiteralControl("</center><br>"))
tbl = New Table
tbl.Width = Unit.Pixel(660)
r = New TableRow
tbl.Rows.Add(r)
btnPrev = New LinkButton
btnPrev.Text = "<Previous " & GetDocumentDescription(lstType) & ">"
btnPrev.ID = "btnPrev"
AddHandler btnPrev.Click, AddressOf ButtonClick
c = New TableCell
c.HorizontalAlign = HorizontalAlign.Left
c.Controls.Add(btnPrev)
c.Width = Unit.Pixel(280)
r.Cells.Add(c)
btnNext = New LinkButton
btnNext.Text = "<Next " & GetDocumentDescription(lstType) & ">"
btnNext.ID = "btnNext"
AddHandler btnNext.Click, AddressOf ButtonClick
c = New TableCell
c.HorizontalAlign = HorizontalAlign.Center
'_pageIndex.ForeColor = Color.DarkBlue
c.Width = Unit.Pixel(100)
c.Controls.Add(_pageIndex)
r.Cells.Add(c)
c = New TableCell
c.HorizontalAlign = HorizontalAlign.Right
c.Controls.Add(btnNext)
c.Width = Unit.Pixel(280)
r.Cells.Add(c)
Dim objTBR As New TBRDocuments(lstType, Session("EmployeeID"),
Session("UserID"))
ContentArea.Controls.Add(New LiteralControl("<br><center>"))
ContentArea.Controls.Add(tbl)
ContentArea.Controls.Add(New LiteralControl("</center><br>"))
End Sub
Public Sub GetDocumentList()
Dim objTBR As New TBRDocuments(lstType, Session("EmployeeID"),
Session("UserID"))
Session("Documents") = objTBR
Session("DocCount") = objTBR.Count
End Sub
Public Sub LoadDocument()
Dim doc As TBRDocuments
doc = CType(Session("Documents"), TBRDocuments)
If Session("DocCount") > 0 Then
_pageIndex.Text = "(" & (Session("DocIndex") + 1).ToString & " of " &
Session("DocCount") & ")"
End If
If doc.Count > 0 Then
CallControl(doc.Documents(Session("DocIndex")))
Else
btnPrev.Visible = False
btnNext.Visible = False
End If
End Sub
Public Sub CallControl(ByVal doc As Document)
Select Case doc.DocumentType
Case enumDocType.Invoice
ctlDoc = Page.LoadControl(Page.ResolveUrl("~/Secure/ctlinvoice.ascx"))
ctlDoc.id = "ctlInvoice"
Case enumDocType.TimesheetMonthly
ctlDoc =
Page.LoadControl(Page.ResolveUrl("~/Secure/ctlTimesheetMonthly.ascx"))
ctlDoc.id = "ctlTimesheetMonthly"
Case enumDocType.TimesheetWeekly
ctlDoc =
Page.LoadControl(Page.ResolveUrl("~/Secure/ctlTimesheetWeekly.ascx"))
ctlDoc.id = "ctlTimesheetWeekly"
End Select
viewstate("docType") = doc.DocumentType
Session("PrintDoc") = doc 'So it can be printed
ctlDoc.CtlDocument = doc
ctlDoc.LoadTimesheet = True
ctlDoc.ListType = lstType
ContentArea.Controls.Add(New LiteralControl("<center>"))
ContentArea.Controls.Add(ctlDoc)
ContentArea.Controls.Add(New LiteralControl("</center>"))
SetNavControls(Session("DocIndex"), Session("DocCount"))
End Sub
Public Sub ButtonClick(ByVal sender As System.Object, ByVal e As
System.EventArgs)
Select Case sender.id
Case "btnPrev"
If Session("DocIndex") > 0 Then
Session("DocIndex") -= 1
RemoveControl(ContentArea.Controls, ctlDoc.id)
LoadDocument()
End If
Case "btnNext"
If Session("DocIndex") + 1 < Session("DocCount") Then
Session("DocIndex") += 1
RemoveControl(ContentArea.Controls, ctlDoc.id)
LoadDocument()
End If
End Select
End Sub
Public Sub SetNavControls(ByVal idx As Integer, ByVal max As Integer)
If max < 2 Then
btnPrev.Visible = False
btnNext.Visible = False
ElseIf idx = 0 Then
btnPrev.Visible = False
btnNext.Visible = True
ElseIf idx < max - 1 Then
btnPrev.Visible = True
btnNext.Visible = True
Else
btnPrev.Visible = True
btnNext.Visible = False
End If
End Sub
> Hi,
>
[quoted text clipped - 24 lines]
> Help!!
> rotsey