Vic Posted January 28, 2004 Posted January 28, 2004 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 Quote
Administrators PlausiblyDamp Posted January 28, 2004 Administrators Posted January 28, 2004 Any chance you could post the relevant code (LoadPostData, RaisePostBackEvent, LoadViewState, SaveViewState and TrackViewState) Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Vic Posted January 28, 2004 Author Posted January 28, 2004 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 Subboxtest.zip Quote
Administrators PlausiblyDamp Posted January 29, 2004 Administrators Posted January 29, 2004 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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Administrators PlausiblyDamp Posted January 29, 2004 Administrators Posted January 29, 2004 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? Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Administrators PlausiblyDamp Posted January 29, 2004 Administrators Posted January 29, 2004 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 ;) Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Vic Posted January 29, 2004 Author Posted January 29, 2004 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 Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.