Killua
Killua

Reputation: 92

Cannot get ASP dynamically created control using FindControl

I have created many dynamic controls. I would now like to find those controls and review their contents on postback before proceeding with the database write.

Controls created as follows:

  For i As Integer = 0 To numberOfSplitItems
    Dim combo As New RadComboBox()
    combo.ID = "MonthSpliCombo" & i
    'Items then added to the combobox
    monthDIV.Controls.Add(combo)
    splitdiv.Controls.Add(MonthDIV)
    PanelActualSplit.Controls.Add(splitdiv)
  Next

This is working 100% and my controls are all added where they should be and are working. I can find all these controls in javascript no problem.

  Protected Sub processSplitMonthsBTN_Click(sender As Object, e As EventArgs)
     For i As Integer = 1 to numberOfSplitItems
      Dim monthBox As New RadComboBox
      Try
        monthBox = DirectCast(PanelActualSplit.FindControl("MonthSpliCombo" & i), RadComboBox)
        MsgBox(monthBox.ClientID)
      Catch ex As Exception
        MsgBox(ex.ToString)
      End Try
     Next
  End Sub

Error it keeps showing: System.NullReferenceException: Object not set to an instance of an object.

I have adjusted as follows to try determine my error: taken out 'DirectCast' tried to use TryCast Dim monthBox as RadComboBox - leave out the 'As New'

I have tried multiple controls, but I cannot seem to get the control saved into the monthBox control so that I can start my validation.

Please could you assist.

Upvotes: 0

Views: 345

Answers (2)

LieBieS
LieBieS

Reputation: 141

The answer is quite simple.

Upon each postback the controls are refreshed, thus losing the controls that were dynamically created on the last postback. Viewstate of the controls needs to be remembered and thus "recreated" on the next postback.

Move your procedure which created the controls into it's own sub and add the following overrides to your code.

  Protected Overrides Function SaveViewState() As Object
    Dim viewState = New Object(1) {}       

    viewState(0) = Integer.Parse(numberOfSplitItems)

    viewState(1) = MyBase.SaveViewState()
    Return viewState
End Function

Protected Overrides Sub LoadViewState(savedState As Object)        
    If TypeOf savedState Is Object() AndAlso DirectCast(savedState, Object()).Length = 2 Then
        Dim viewState = DirectCast(savedState, Object())
        Dim count = Integer.Parse(viewState(0).ToString())
        yourAddcontrolsProceduresHere(count)
        MyBase.LoadViewState(viewState(1))
    Else
        MyBase.LoadViewState(savedState)
    End If
End Sub

That will solve the issue and reload the controls on your postback thus allowing the server to access find them and you will no longer have the Null reference exception.

Upvotes: 1

SmartDev
SmartDev

Reputation: 2862

Instead of PanelActualSplit.FindControl you should use a function similar to this:

public static Control FindControlRecursive(Control ctl, string id) {
    if (!ctl.HasControls())
        return null;
    Control res = null;
    foreach(Control c in ctl.Controls) {
        if (c.ID == id) {
            res = c;
            break;
        } else {
            res = FindControlRecursive(c, id);
            if (res != null)
                break;
        }
    }
    return res;
}

in this way:

RadComboBox monthBox = (Table)FindControlRecursive(PanelActualSplit, "MonthSpliCombo" & i);

And you will find your control for sure.

Upvotes: 0

Related Questions