Control WON'T Lose State!!

Last post 08-21-2008 11:27 AM by shados. 11 replies.

Sort Posts:

  • Control WON'T Lose State!!

    08-19-2008, 1:53 PM
    • Member
      38 point Member
    • pawicks
    • Member since 06-26-2008, 3:46 PM
    • Posts 31

    I previously posted because I couldn't get my custom control to maintain it's state.  Now that I have that fixed I can't get it to lose it's state!

    My control is a 2 axis table with dates running along the top and tasks along the left hand column.  For each task/date intersection there is a textbox that contains a decimal value which is loaded from a database.  If I enter a value into a textbox, who's default value is 0, the value will will still be there on postback. When I rebuild the control using new data, the previously entered value remains along with any values that were loaded from the previous dataset along with all of the new values from the current dataset, though usually the old values get shifted around a few cells/columns due to the change in task or date count.  The values are apparently loaded from state... The dates and task names do update properly.

    The control is being dynamically added to the page on every page load and the appropriate information loaded in during the controls OnInit phase, before the state loads.  I have also tried binding the data after the control has been added to the page, instead of during the OnInit phase, but it made no difference.  I have tried calling ClearChildControlState at various locations but with no success.

    How can I clear out the saved "state" of my control before rebuilding it with new data?

    Any help would be greatly appreciated.

    Thanks,

       --Peter

  • Re: Control WON'T Lose State!!

    08-19-2008, 3:19 PM
    • Star
      12,126 point Star
    • shados
    • Member since 07-07-2006, 11:24 PM
    • Posts 2,202

    Careful about one part: "and the appropriate information loaded in during the controls OnInit phase, before the state loads"

    Reload the -control- in Init, but reload its -data- in page load. Otherwise, here is what happens:

    -You recreate your control.

    -You add the new data to it.

    -Viewstate is reloading, overriding your new data with the old.

    -Then page load occures.

     I'm not sure thats your problem, but from the bit of info you gave, thats what I can deffer. Also, next time you have to do something like this, look into making a custom CompositeControl, as it handles all that mess for you.

  • Re: Control WON'T Lose State!!

    08-19-2008, 6:38 PM
    • Member
      38 point Member
    • pawicks
    • Member since 06-26-2008, 3:46 PM
    • Posts 31

    I took your advice and rebuilt the control as a composite control. In my inexperience it took me about an hour and a half, with most of the code just copying and pasting over, but in the end it works perfectly and I no longer have to reload the data each time, just once, the way it's supposed to be.  It's super awesome.

    Thanks Allot.

  • Re: Control WON'T Lose State!!

    08-20-2008, 9:23 AM
    • Star
      12,126 point Star
    • shados
    • Member since 07-07-2006, 11:24 PM
    • Posts 2,202

    What? An hour and a half without experience to get the hang of composite control and get it working? That is quite impressive.

    Considering this is a recurring issue people have, could you give me your references on where you learned, so that I can suggest them to others who have similar issues as you (which is several people, every day it seems)?

    Thank you!

  • Re: Control WON'T Lose State!!

    08-20-2008, 4:11 PM
    • Member
      38 point Member
    • pawicks
    • Member since 06-26-2008, 3:46 PM
    • Posts 31

     *puts on the breaks*

    Guess it's not all working quite as awesome as I thought :(  All of the data loads fine, and displays fine, and posts back fine, and if I make changes and click my save button it even saves back to the database fine.  Everything works 100% perfect up until after I click the "Save" button.

    Inside of my grid of "Text boxes" I actually use another custom control that inherits from TextBox.  If I put a break point on it's overridden Text property I can verify that anytime I change a value in one of the text boxes and I post back, before I click the Save button, the Set portion is being hit.  After I click the Save button this no longer happens, which causes the value to not be stored, and thus be lost.

    I added a Button to my form for the purpose of just posting back the page.  If I click the "Save" button, then click the Post Back button, and then try to change values in text boxes again everything is fine.  It's only if I try to change values right after a save and before another post back has occurred that I run into this issue.

    Any help with this issue would be Greatly appreciated.

    --Peter

    Save Code:

     

    '--Inside of the Main Control--
    Public Sub SaveData()
    '--------Save Data--------
    Dim DoseContext As New DoseReportingDataContext()
    'for each row in the dates table
    For Each tr As TableRow In DatesTable.Rows
    'For each cell in the row
    For Each td As TableCell In tr.Cells
    'check if child control exists
    If td.Controls.Count > 0 Then
    'if child control is an estimated dose item
    If TypeOf td.Controls(0) Is EstimatedDoseItem Then
    'save data
    Dim edi As EstimatedDoseItem = td.Controls(0)
    edi.Save(DoseContext)
    End If
    End If
    Next
    Next


    'Update all database records that may have changed
    DoseContext.SubmitChanges()
    End Sub

    '--Inside of the control that inherits from TextBox
    Public Sub Save(ByRef DataContext As DoseReportingDataContext)
    'if this is an existing entry then retrieve the original attached version and update it's estimate, or delete it if appropriate
    If EstimateID <> 0 Then
    'Get the record from the DB with all of the original values
    Dim original = (From c In DataContext.DoseEstimates Where c.EstimateID = EstimateID Select c).First()

    'if Dose Estimate entered then update the value in the db
    If EstimatedDose <> 0D Then
    'Update original with new value
    original.EstimatedDose = EstimatedDose
    'Optimistic concurencty will take care of actually updating the record in the DB
    Else
    'If no dose value present then delete the original record
    DataContext.DoseEstimates.DeleteOnSubmit(original)
    End If
    Else

    'if this is a new entry, and it has data
    If EstimatedDose <> 0D Then
    DataContext.DoseEstimates.InsertOnSubmit(GetDoseEstimate())
    End If
    End If
    End Sub
      
  • Re: Control WON'T Lose State!!

    08-20-2008, 4:40 PM
    • Star
      12,126 point Star
    • shados
    • Member since 07-07-2006, 11:24 PM
    • Posts 2,202

    Its hard to tell from that code, but there's a few things to know about CompositeControls.

    First: Don't create your child controls in the constructor. Do it in the CreateChildControls method (override it).

    Anytime you need to get the values or state of child controls, make sure you call EnsureChildControls first.

    Then, anytime you do anything with your control that should require controls to be recreated, make sure to do a ChildControlsCreated = false; Do note that you will lose the state of your child controls though when that happens, but there's no choice.

    Now, here is where your issue could occure: If you are creating controls in the constructor or some other event of the composite control, they will not be created correctly, and sometimes, ViewState will not be reloaded properly. If that happens, when you save, events won't be fired, values won't be correct, and so on.

    Another possibility if you are not creating your controls properly, is that you'll actually end with TWO sets of textbox. So the text property will be set on the wrong one, and all hell breaks lose.

    Before we continue the diagnostic, can you confirm that you're doing the stuff I just talked about properly, to eliminate that as a source of problems? 

  • Re: Control WON'T Lose State!!

    08-20-2008, 5:12 PM
    • Member
      38 point Member
    • pawicks
    • Member since 06-26-2008, 3:46 PM
    • Posts 31

    I am creating my controls in "CreateChildControls" method.  I did not have any entries for ChildControlsCreated=false or EnsureChildControls() but I have added these, which has not made any difference as far as solving the issue goes.

    I have included my full code below, hopefully that will help.

    Thanks,
      --Peter

     

     

    '--Main Control--

    <ToolboxData("<{0}:EstimatesControl runat=server />")> _
    Public Class EstimatesControl
    Inherits CompositeControl

    Dim DoseContext As DoseReportingDataContext

    Public Property DataDate() As DateTime
    Get
    Dim
    o As Object = ViewState("DataDate")
    If Not o Is Nothing Then
    Return
    Convert.ToDateTime(o)
    Else
    Return
    DateTime.MinValue
    End If
    End Get
    Set
    (ByVal value As DateTime)
    ViewState("DataDate") = value
    End Set
    End Property

    Public Property
    DisplayStartDate() As DateTime
    Get
    Dim
    o As Object = ViewState("DisplayStartDate")
    If Not o Is Nothing Then
    Return
    Convert.ToDateTime(o)
    Else
    Return
    DateTime.MinValue
    End If
    End Get
    Set
    (ByVal value As DateTime)
    ViewState("DisplayStartDate") = value
    End Set
    End Property

    Public Property
    DisplayEndDate() As DateTime
    Get
    Dim
    o As Object = ViewState("DisplayEndDate")
    If Not o Is Nothing Then
    Return
    Convert.ToDateTime(o)
    Else
    Return
    DateTime.MinValue
    End If
    End Get
    Set
    (ByVal value As DateTime)
    ViewState("DisplayEndDate") = value
    End Set
    End Property

    Public Property
    Department() As Integer
    Get
    Dim
    o As Object = ViewState("Department")
    If Not o Is Nothing Then
    Return
    Convert.ToInt32(o)
    Else
    Return
    -1
    End If
    End Get
    Set
    (ByVal value As Integer)
    ViewState("Department") = value
    End Set
    End Property


    'Master Panel that will surround the two table
    Protected ParentPanel As Panel
    'Main Table used for layout
    Protected LayoutTable As Table

    'Row and Cells for layout table
    Protected LayoutRow As TableRow
    Protected TasksCell As TableCell
    Protected DatesCell As TableCell

    'Main Tasks table
    Protected TasksTable As Table

    'Scrolling Panel that DatesTable goes in
    Protected DatesPanel As Panel

    'Main Dates Table
    Protected DatesTable As Table


    Public Sub New()
    DoseContext = New DoseReportingDataContext()
    End Sub


    Protected Overrides Sub
    CreateChildControls()
    Me.Controls.Clear()

    'get data record count
    Dim RecordCount As Integer = ViewState("RecordCount")

    'Master Panel that will surround the two table
    ParentPanel = New Panel()
    'Main Table used for layout
    LayoutTable = New Table()

    'Row and Cells for layout table
    LayoutRow = New TableRow()
    TasksCell = New TableCell()
    DatesCell = New TableCell()

    'Main Tasks table
    TasksTable = New Table()

    'Scrolling Panel that DatesTable goes in
    DatesPanel = New Panel()

    'Main Dates Table
    DatesTable = New Table()

    'Verify that StartDate is assigned, if not autogenerate
    If DataDate = DateTime.MinValue Then
    AutoGenerateDates(DateTime.Now.AddDays(-DateTime.Now.Day + 1))
    ElseIf DataDate = DateTime.MinValue Then
    'if start date assigned but end date not then use startdate as seed
    AutoGenerateDates(DataDate)
    End If
    '----Create Child Controls---

    '--Put Controls Together--'

    BirthChildren()

    'Create Date Headers and Tasks Main Header
    CreateHeaders(DisplayStartDate, DisplayEndDate)

    'Create empty shell for data if row count known
    If Not ViewState("RecordCount") = Nothing Then
    Dim
    i As Integer = 0

    While i < RecordCount
    '-Create blank task-
    CreateTasksEntry(Nothing)

    '--Load per date info for each Dose Estiamte--
    'Copy the Start Date

    Dim TaskDate As DateTime = DisplayStartDate
    'Create table row for this work orders date info
    Dim tr As TableRow = New TableRow()

    'while we have not passed the end date
    While TaskDate <= DisplayEndDate
    'Load empty entry
    AddDatedEntry(tr, TaskDate, Nothing)

    'Increment the date by 1
    TaskDate = TaskDate.AddDays(1)
    End While

    'Add in the Row
    DatesTable.Rows.Add(tr)
    'Increment i
    i += 1
    End While
    End If

    MyBase
    .CreateChildControls()
    End Sub

    Protected Sub
    ClearOldData()
    'Clear out all old rows, including header
    TasksTable.Rows.Clear()
    DatesTable.Rows.Clear()
    End Sub

    Private Sub
    BirthChildren()
    '--Put Controls Together--'
    'Add parent Panel to parent control

    Controls.Add(ParentPanel)

    'Add layout table to ParentPanel
    ParentPanel.Controls.Add(LayoutTable)

    'Add layout row
    LayoutTable.Rows.Add(LayoutRow)

    'Add layout cells
    LayoutRow.Cells.Add(TasksCell)
    LayoutRow.Cells.Add(DatesCell)

    'Load Tasks Table into Parent Panel
    TasksCell.Controls.Add(TasksTable)

    'Load Dates Panel into Parent Panel
    DatesCell.Controls.Add(DatesPanel)

    'Load Dates Table into DatesPanel
    DatesPanel.Controls.Add(DatesTable)

    '--Set specific properties on controls
    'Set Tasks Table cell padding/spacing

    TasksTable.CellPadding = 0
    TasksTable.CellSpacing = 0
    'Set scrollbars and width of dates panel
    DatesPanel.ScrollBars = ScrollBars.Horizontal
    DatesPanel.Style.Add("width", "600px")
    'Set cell padding/spacing of Dates Table
    DatesTable.CellPadding = 0
    DatesTable.CellSpacing = 0
    End Sub

    Public Sub
    LoadData()
    'Ensure Child Controls Created
    EnsureChildControls()
    'if no department assigned or this control is not visible then return without loading data
    If Department <= 0 Or Not Me.Visible Then
    Return
    End If


    '--Clear Old Data--
    ClearOldData()

    '-Create new headers-
    CreateHeaders(DisplayStartDate, DisplayEndDate)

    '---Get All labor entries that start in this month/year for this department---
    Dim monthlyLaborData = From c In DoseContext.Labors _
    Where (c.StartDate.Month = DataDate.Month And c.StartDate.Year = DataDate.Year) And c.DepartmentID = Department _
    Select c

    Dim data As IEnumerable(Of Labor) = monthlyLaborData.AsEnumerable()

    'Get count and verify records exist
    Dim RecordCount As Integer = data.Count()

    'if no data found then return
    If RecordCount <= 0 Then
    'We should have a No Data Template sort of thing that gets displayed here
    ' but for now just return

    Return
    Else

    ViewState("RecordCount") = RecordCount
    End If



    '---Create Rows and Cells---'
    'Basic objects to use for table creation

    Dim tr As TableRow = Nothing
    Dim
    td As TableCell = Nothing

    'Create Table stuff for this work order
    Dim LaborCurrentCount As Integer = 0 'used to track our progress through the list
    'Loop through Labor records

    While LaborCurrentCount < RecordCount
    'Get the Labor entry for this row
    Dim CurrentLaborEntry As Labor = data(LaborCurrentCount)

    'Empty DoseEstimate with basic info in it such as labor ID
    Dim EmptyEstimate As New DoseEstimate()
    EmptyEstimate.EstimateID = 0
    EmptyEstimate.LaborID = CurrentLaborEntry.LaborID
    EmptyEstimate.EstimatedDose = 0D

    '-Create the entry in the Tasks table-
    CreateTasksEntry(CurrentLaborEntry)

    '--Load per date info for each Dose Estiamte--
    'Copy the Start Date

    Dim TaskDate As DateTime = DisplayStartDate
    'Create table row for this work orders date info
    tr = New TableRow()

    'Add in the Row
    DatesTable.Rows.Add(tr)

    'while we have not passed the end date
    While TaskDate <= DisplayEndDate
    'Change date on empty dose estimate
    EmptyEstimate.DateForEstimate = TaskDate
    'See if there are any Estimates for this day/Labor Entry
    Dim estimates = From c In CurrentLaborEntry.DoseEstimates Where c.DateForEstimate.Date = TaskDate.Date Select c

    If estimates.Count > 0 Then
    'Get Dose Estimate, should only be one per day per labor entry
    Dim DoseEstimate As DoseEstimate = estimates.First()

    AddDatedEntry(tr, TaskDate, DoseEstimate)
    Else
    AddDatedEntry(tr, TaskDate, EmptyEstimate)
    End If

    'Increment the date by 1
    TaskDate = TaskDate.AddDays(1)
    End While

    'Move onto the next work order
    LaborCurrentCount += 1
    End While
    End Sub

    Protected Sub
    CreateTasksEntry(ByRef Labor As Labor)
    '--Create the entry in the Tasks table--'

    'Create new row for work orders table

    Dim tr As TableRow = New TableRow()

    'Add new cell with Work Order name/number
    Dim td As TableCell = New TableCell()

    'Set standard height on the cell
    td.Height = New WebControls.Unit(30, UnitType.Pixel)

    'Create Task Label
    Dim lblTask As New Label()

    'Add Label Control to TableCell
    td.Controls.Add(lblTask)

    'Add cell to row
    tr.Cells.Add(td)

    'Add row to work orders table
    TasksTable.Rows.Add(tr)

    'if labor is not null then use blank for text and tooltip
    If Not Labor Is Nothing Then
    'Set text and tooltip
    lblTask.Text = Labor.AlaraTask.WorkOrderTask.WorkOrder + ":" + Labor.AlaraTask.TaskNumber.ToString("00") + ":" + Labor.AlaraTask.TaskNumber.ToString("00")
    lblTask.ToolTip = Labor.AlaraTask.AlaraDescription + Environment.NewLine + Labor.AlaraTask.AlaraSubDescription
    End If

    End Sub

    Protected Sub
    AddDatedEntry(ByRef Row As TableRow, ByVal TaskDate As DateTime, ByVal DoseEstimate As DoseEstimate)
    '--Create Entry for this day in this row--

    'new table cell for this day

    Dim td As TableCell = New TableCell()
    'Add cell to the row
    Row.Cells.Add(td)
    'set to uniform height
    td.Height = New WebControls.Unit(30, UnitType.Pixel)

    'Check for holidays/weekend
    HandleSpecialDays(td, TaskDate)

    'Used to hold our data for this Task/Date
    Dim dData As New EstimatedDoseItem()
    td.Controls.Add(dData)

    If Not DoseEstimate Is Nothing Then
    'Load in DoseEstimate values, we load it now instead of on instantiatoin because we need to it to be tracked in ViewState
    dData.EstimateID = DoseEstimate.EstimateID
    dData.LaborID = DoseEstimate.LaborID
    dData.DateForEstimate = DoseEstimate.DateForEstimate
    dData.EstimatedDose = DoseEstimate.EstimatedDose
    Else
    dData.EstimateID = 0
    dData.LaborID = 0
    dData.DateForEstimate = TaskDate
    dData.EstimatedDose = 0D
    End If


    '--Old TextBox Version--
    ''Used to hold our data for this Task/Date
    'Dim dData As New TextBox()
    ''Add the Estimated Dose Item to the TD
    'td.Controls.Add(dData)

    ''Load in EstimatedDose as text value
    'dData.Text = EstimatedDose
    ''Set textbox column width to 5
    'dData.Columns = 5

    End Sub

    Protected Sub
    CreateHeaders(ByVal StartDate As DateTime, ByVal EndDate As DateTime)
    'Basic objects to use for table creation
    Dim tr As TableRow = Nothing
    Dim
    td As TableCell = Nothing

    '--Add in Work Orders Header--
    tr = New TableRow()
    td = New TableCell()
    td.Text = "Tasks"
    'make "Work Orders" bold
    td.Style.Add("font-weight", "bold")
    'Add the cell to the row
    tr.Cells.Add(td)
    'add the "header" row to the work orders table
    TasksTable.Rows.Add(tr)

    '--Add in Dates Header for this month--
    'New table row to hold date cells

    tr = New TableRow()
    'Used to hold current date
    Dim CurrentDate As DateTime = StartDate
    'While we have not passed the end date
    While CurrentDate <= EndDate
    td = New TableCell()
    td.Text = CurrentDate.ToShortDateString()
    'Handle Holiday/Weekend coloring/marking
    HandleSpecialDays(td, CurrentDate)
    'Make Date bold
    td.Style.Add("font-weight", "bold")
    'Add date to header row
    tr.Cells.Add(td)
    'Increment the date by 1
    CurrentDate = CurrentDate.AddDays(1)
    End While
    'Add in the Dates header
    DatesTable.Rows.Add(tr)
    End Sub

    Protected Sub
    HandleSpecialDays(ByRef TD As TableCell, ByVal SelectedDate As DateTime)
    'Later on we will add a Special Days table to the database so we can highlight special days for reporting/etc
    If SelectedDate.DayOfWeek = DayOfWeek.Saturday Or SelectedDate.DayOfWeek = DayOfWeek.Sunday Then
    TD.BackColor = Drawing.Color.LightSkyBlue
    TD.ToolTip = "Weekend"
    End If
    End Sub

    Public Sub
    AutoGenerateDates(ByVal Seed As DateTime)
    DataDate = New DateTime(Seed.Year, Seed.Month, 1)

    'Also set Display Dates values
    DisplayStartDate = DataDate
    DisplayEndDate = DataDate.AddMonths(1).AddDays(-1)
    End Sub

    Public Sub
    SaveData()
    '--------Save Data--------
    Dim DoseContext As New DoseReportingDataContext()
    'for each row in the dates table
    For Each tr As TableRow In DatesTable.Rows
    'For each cell in the row
    For Each td As TableCell In tr.Cells
    'check if child control exists
    If td.Controls.Count > 0 Then
    'if child control is an estimated dose item
    If TypeOf td.Controls(0) Is EstimatedDoseItem Then
    'save data
    Dim edi As EstimatedDoseItem = td.Controls(0)
    edi.Save(DoseContext)
    End If
    End If
    Next
    Next


    'Update all database records that may have changed
    DoseContext.SubmitChanges()
    ChildControlsCreated = False
    End Sub
    End Class


    '--Inherits from TextBox Control--
    Public Class EstimatedDoseItem
    Inherits TextBox

    Public Event DoseChanged As EventHandler

    'Override Text property of textbox so that it references the Estimated Dose
    Public Overrides Property Text() As String
    Get
    Return
    EstimatedDose.ToString()
    End Get
    Set
    (ByVal value As String)
    EstimatedDose = Convert.ToDecimal(value)
    End Set
    End Property

    Public ReadOnly Property
    DoseEstimate() As DoseEstimate
    Get
    Return
    GetDoseEstimate()
    End Get
    End Property

    Public Property
    EstimateID() As Integer
    Get
    Dim
    o As Object = ViewState("EstimateID")
    If Not o Is Nothing Then
    Return
    Convert.ToInt32(o)
    Else
    Return
    0
    End If
    End Get
    Set
    (ByVal value As Integer)
    ViewState("EstimateID") = value
    End Set
    End Property


    Public Property
    LaborID() As Integer
    Get
    Dim
    o As Object = ViewState("LaborID")
    If Not o Is Nothing Then
    Return
    Convert.ToInt32(o)
    Else
    Return
    0
    End If
    End Get
    Set
    (ByVal value As Integer)
    ViewState("LaborID") = value
    End Set
    End Property

    Public Property
    DateForEstimate() As DateTime
    Get
    Dim
    o As Object = ViewState("DateForEstimate")
    If Not o Is Nothing Then
    Return
    Convert.ToDateTime(o)
    Else
    Return
    DateTime.MinValue
    End If
    End Get
    Set
    (ByVal value As DateTime)
    ViewState("DateForEstimate") = value
    End Set
    End Property

    Public Property
    EstimatedDose() As Decimal
    Get
    Dim
    o As Object = ViewState("EstimatedDose")
    If Not o Is Nothing Then
    Return
    Convert.ToDecimal(o)
    Else
    Return
    0D
    End If
    End Get
    Set
    (ByVal value As Decimal)
    ViewState("EstimatedDose") = value
    End Set
    End Property

    Public Sub New
    ()

    End Sub

    Public Function
    GetDoseEstimate() As DoseEstimate
    Dim DoseEstimate As New DoseEstimate()

    With DoseEstimate
    .EstimateID = EstimateID
    .DateForEstimate = DateForEstimate
    .LaborID = LaborID
    .EstimatedDose = EstimatedDose
    End With

    Return
    DoseEstimate
    End Function

    Protected Overrides Sub
    OnLoad(ByVal e As System.EventArgs)
    'On load change the width of the txt box
    Me.Columns = 5
    'Center the text
    Me.Style.Add("text-align", "center")
    MyBase.OnLoad(e)
    End Sub

    Protected Overrides Sub
    OnTextChanged(ByVal e As System.EventArgs)
    RaiseEvent DoseChanged(Me, e)
    MyBase.OnTextChanged(e)
    End Sub

    'This function saves the data in the cell back to the database
    Public Sub Save(ByRef DataContext As DoseReportingDataContext)
    'if this is an existing entry then retrieve the original attached version and update it's estimate, or delete it if appropriate
    If EstimateID <> 0 Then
    'Get the record from the DB with all of the original values
    Dim original = (From c In DataContext.DoseEstimates Where c.EstimateID = EstimateID Select c).First()

    'if Dose Estimate entered then update the value in the db by attaching it
    If EstimatedDose <> 0D Then
    'Update original with new value
    original.EstimatedDose = EstimatedDose
    'Optimistic concurencty will take care of actually updating the record in the DB
    Else
    'If no dose value present then delete the original record
    DataContext.DoseEstimates.DeleteOnSubmit(original)
    End If
    Else

    'if this is a new entry, and it has data
    If EstimatedDose <> 0D Then
    DataContext.DoseEstimates.InsertOnSubmit(GetDoseEstimate())
    End If
    End If
    End Sub
    End Class

      
  • Re: Control WON'T Lose State!!

    08-20-2008, 6:52 PM
    • Star
      12,126 point Star
    • shados
    • Member since 07-07-2006, 11:24 PM
    • Posts 2,202

    Hmm, I'm looking at it again and again, and I don't see any flaws... you don't have to clear the controls in ChildControlCreation since thats done automatically, but it wouldn't change anything. Its pretty good code, too.

    Now, I'm a bit stumped... considering you say that a normal postback "fixes" it... when are the postbacks where the behavior break? Are the custom textbox using AutoPostBack and its what not working? I'd also be curious, is there anything special in your Save/Submit button, besides calling the Save method of your control? Something that could break stuff?

  • Re: Control WON'T Lose State!!

    08-20-2008, 7:06 PM
    • Member
      38 point Member
    • pawicks
    • Member since 06-26-2008, 3:46 PM
    • Posts 31

     The custom textboxes do not AutoPostBack or anything like that. I'll give a better breakdown of what happens.

    1.  The Page loads and I choose what data I want to load from the parent page which then populates the Department property along with the date properties
    2. Once the properties are assigned I call the LoadData Method to load up all of the data for the specified properties
    3. Once the data Loads I change a value, or several if I wish, either an existing one or one of the 0's to create a new entry in the database.
    4. I click the save button on the main page
       --Save Button Code--
          Protected Sub ibSave_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles ibSave.Click
      'Execute Save Request
      EstimatesControl1.SaveData()
      'Load the Data
      EstimatesControl1.LoadData()
      End Sub
    5. As you can see in the save button code, the sub routine calls the SaveData method and then re-Loads the Data in the control.
    6. After this the page loads up normally with all updated information present.
    7. Now I go to make an additional change, so I change a value in a textbox and click save.  When I click save the value reverts to it's previous state and does not update in the DB either.
    8. If I enter a value and click the Postback button this happens also, the first time anyways.
    9. If I enter a value, click the postback button, value disappears, then I enter the value again and click the postback button, the value will remain.
    10. Or if I enter a value, click the postback button, value disappears, enter the value again and click save it saves properly.
    11. After a successful save this process repeates over and over again.

    Thanks for the help.

    --Peter

  • Re: Control WON'T Lose State!!

    08-21-2008, 9:45 AM
    • Star
      12,126 point Star
    • shados
    • Member since 07-07-2006, 11:24 PM
    • Posts 2,202

    Ok, that helps a bit. Looking at it real quick (I got late for work today, so I don't have as much time as I'd like), doesn't your LoadData method recreate some of the controls? I'd try to see if you only leave SaveData or LoadData (but not both) in the save button. Of course that will break your behavior, but I'm wondering if that would prefer it from breaking the texboxes... Because the inner controls aren't manipulated fully inside the CreateChildControl, you may end with duplicate childs and stuff.

  • Re: Control WON'T Lose State!!

    08-21-2008, 10:30 AM
    Answer
    • Member
      38 point Member
    • pawicks
    • Member since 06-26-2008, 3:46 PM
    • Posts 31

     I GOT IT!!!!

    You were right to a point, ther was some stuff going on in the LoadData section that was causing for some of the previously created controls to get re-made, and then they would get removed and overwritten with the new ones.  So no duplicates would appear on the screen but still was causing issues I guess. I changed the following pieces of the LoadData method and it now works nicely.  Reseting the RecordCount viewstate object was a crucial step, that way when I EnsureChildControls I don't get any empty records created.

    Not surprisingly my code is even a little bit cleaner.  What actually helped me figure out that it was in LoadData was that I was able to re-produce the same effect as the save button issue by loading a different departments data.  So it turned out that if you Run LoadData on top of the existing loaded data without making sure it gets cleared properly first that the issue occured.

    Thanks for all your help.  Now hopefully I won't run into any issues.
        --Peter

     CODE:

        Public Sub LoadData()
            ChildControlsCreated = False
            'Set recordcount to nothing so that everything gets cleared properly
            ViewState("RecordCount") = Nothing
            'Re-Create all main child controls
            EnsureChildControls()
    
            'if no department assigned or this control is not visible then return without loading data
            If Department <= 0 Or Not Me.Visible Then
                Return
            End If
    
            'This is now taken care of by ChildControlsCreated = false
            ''--Clear Old Data--
            'ClearOldData()
    
            'This is now handeled by EnsureChildControls
            ''-Create new headers-
            'CreateHeaders(DisplayStartDate, DisplayEndDate)
    '... rest of code is the same ...
      
  • Re: Control WON'T Lose State!!

    08-21-2008, 11:27 AM
    • Star
      12,126 point Star
    • shados
    • Member since 07-07-2006, 11:24 PM
    • Posts 2,202
    Woohoo! Took a while, but I'm glad you got things working :)
Page 1 of 1 (12 items)