Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Hi,

 

I am authoring a webcontrol and am having difficulties with viewstate and IPostBackDataHandler.

 

My control basically a grid control that renders a bunch of controls in a htmlTAble, and it all works great except for the fact that I dont seem to be able to pick up on changes made in text boxes and combos etc

 

 

THis is really 2 questions sort of mixed up:

 

1) how come sometimes, even though I have overriden LoadPostData, it doesnt fire? I have tried snippets of code from samples and it DOES fire??? what could I be doing wrong? I dont seem to be doing anything different?

 

2) I have overriden save and load viewsate in such a way that I put all the vals from viewstate back into my control. ALl I am getting is the same values back - which are different from the values in found in Request.Form ( as expected) Am I misunderstanding viewstate here?

 

 

I thought the idea was that you use viestate to reconstruct your control and then respond to changes when LoadPostData is fired?

 

The samples and docs are a nightmare. Anyone point me in theright direction?

 

Cheers

Posted

I have made a simplified version for the sake of clarity

 

THere is no PostbackData code yet as I cannot get it to fire

THe viewstate stuff follows but to make more sense, I have attached proj with one simple control full of textboxes and a submit button

 

On 1st page load control is created and filled with 6 textboxes each with distinct values. The text data is saved to viewstate as below. When i click on a submit button, the values are retrieved from viewstate and placed into the textboxes on rendering again.

 

THis all goes swimmingly well except that the values retreived are the same as those sent, even if I edit the values before clicking the submit button.

 

Yes I could get the values from the page.request.form.Allkeys and manually check which values have changed, but this all smells of wrongness. Surely I am missing something obvious here. Surely LoadPostData should tell me about changed values???

 

Please check out attached projette

 

ANd thanks in advance to anyone who has a look.

 

Cheers

 

VIc

 

Protected Overrides Function SaveViewState() As Object

Dim iRow As Integer

Dim sControl As String

Dim sVal As String

For iRow = 1 To BoxCount

sControl = GetControlName(iRow)

sVal = Data(iRow)

ViewState(sControl) = sVal

Next

ViewState("BoxCount") = BoxCount.ToString

Return MyBase.SaveViewState

End Function

 

Protected Overrides Sub LoadViewState(ByVal savedState As Object)

Dim iRow As Integer

Dim sControl As String

Dim sVal As String

 

If Not savedState Is Nothing Then

MyBase.LoadViewState(savedState)

 

BoxCount = CType(ViewState("BoxCount"), Integer)

For iRow = 1 To BoxCount

sControl = GetControlName(iRow)

sVal = ViewState(sControl)

Data(iRow) = sVal

Next

End If

 

End Sub

boxtest.zip

  • Administrators
Posted

Odd indeed, have had a quick look but can't see anything obvious - then again it's getting late....

Will have more time to have a look tomorrow though. If you find anything post here - if not I'll see what I can do tomorrow.

Just out of interest have you looked at implementing an overrided TrackViewState - can't remember exactly if this will help but IIRC it does help to track modified ViewState entries.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

  • Administrators
Posted
Just had another thought - will investigate more tomorrow. But do you need to be involved with the LoadViewstate / saveviewstate yourself - that would normally only be required if you are persisting complex data types - would you not be able to just store the values direct into ViewState?

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

  • Administrators
Posted

Here we go ;)

 

Imports System.Web.UI
Imports System.Web.UI.HtmlControls
Imports System.Web.UI.WebControls

Public Class BoxList
   Inherits System.Web.UI.WebControls.WebControl
Implements IPostBackDataHandler	'we need to handle postback ourselves
Implements INamingContainer   ' generate unique names for child controls

'array of textboxes our control will contain
Dim TextBoxes() As TextBox

Public Property BoxCount() As Integer
	'Store property in viewstate
	Get
		Return Convert.ToInt32(ViewState("BoxCount"))
	End Get
	Set(ByVal Value As Integer)
		viewstate("BoxCount") = Value.ToString
	End Set
End Property

Public Property Data(ByVal Index As Integer) As String
	'Store property in ViewState
	Get
		Return ViewState("Data" & Index).ToString
	End Get
	Set(ByVal Value As String)
		ViewState("Data" & Index) = Value
	End Set
End Property

#Region " RENDER "


Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)

	Dim iBox As Integer

	AddAttributesToRender(output)
	output.RenderBeginTag(HtmlTextWriterTag.Table)	   'Table

	For iBox = 0 To BoxCount - 1
		output.RenderBeginTag(HtmlTextWriterTag.Tr)
		output.RenderBeginTag(HtmlTextWriterTag.Td)

		With TextBoxes(iBox)
			.Text = Data(iBox)
			.ID = "TextBox" & iBox
			.Width = Me.Width
			.RenderControl(output)
		End With

		output.RenderEndTag()			'td
		output.RenderEndTag()			'tr
	Next

	output.RenderEndTag()		 'table

End Sub
#End Region

'Dummy C'to for now
Sub New()
	BoxCount = 6
	ReDim TextBoxes(BoxCount - 1)

End Sub

Public Function LoadPostData(ByVal postDataKey As String, ByVal postCollection As System.Collections.Specialized.NameValueCollection) As Boolean  _
Implements System.Web.UI.IPostBackDataHandler.LoadPostData
	'Never Gets fired
	Dim i As Integer
	For i = 0 To BoxCount - 1
		'only update the viewstate if things have changed
		If ViewState("Data" & i).ToString <> postCollection(TextBoxes(i).UniqueID) Then
			ViewState("Data" & i) = postCollection.Item(TextBoxes(i).UniqueID)

		End If
	Next

End Function

Public Sub RaisePostDataChangedEvent() Implements System.Web.UI.IPostBackDataHandler.RaisePostDataChangedEvent

End Sub

Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
	Page.RegisterRequiresPostBack(Me)	   'notify framework we need postback notification
	MyBase.OnInit(e)
	Dim i As Integer

	'create our controls....
	For i = 0 To BoxCount - 1
		TextBoxes(i) = New TextBox
		TextBoxes(i).ID = "TextBox" & i
		Me.Controls.Add(TextBoxes(i))
	Next
End Sub
End Class

 

seems to work under very casual testing. In reality should have a few more error traps etc. Let me know if it solves your problem / doesn't solve your problem / fails utterly in every respect and I can have another look / feel really glad I recently decided to learn asp.net server controls ;)

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

Mr Damp,

 

 

I cant tell you how grateful I am. I haven't got round to implementing your stuff yet but I can see at a glance that it addresses all the right questions. I wil try out and sew in the main points into my grid control - with 2 dimensional arraay of data and dynamically assignable control types and styles by column - I will post a reply to this thread to let you know how I got on.

 

THanks again for taking the time. It is very much appreciated.

 

VIc

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...