使用FindControl无法获得ASP动态创建的控件

时间:2014-11-14 09:37:54

标签: asp.net vb.net

我创建了许多动态控件。我现在想要在继续​​数据库写入之前找到这些控件并在回发时查看它们的内容。

按如下方式创建的控件:

  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

这是100%工作,我的控件全部添加到它们应该的位置并且正在工作。 我可以在javascript中找到所有这些控件没问题。

  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

它一直显示的错误:System.NullReferenceException:对象未设置为对象的实例。

我已调整如下以尝试确定我的错误:   取出' DirectCast'   试图使用TryCast   Dim monthBox作为RadComboBox - 省略了新的'

我尝试了多个控件,但我似乎无法将控件保存到monthBox控件中,以便我可以开始验证。

请你帮忙。

2 个答案:

答案 0 :(得分:1)

答案很简单。

每次回发时都会刷新控件,从而丢失在上次回发时动态创建的控件。 需要记住控件的视图状态,从而在下一次回发时“重新创建”。

将创建控件的过程移动到它自己的sub中,并将以下覆盖添加到代码中。

  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

这将解决问题并重新加载回发上的控件,从而允许服务器访问查找它们,并且您将不再具有Null引用异常。

答案 1 :(得分:0)

而不是PanelActualSplit.FindControl你应该使用类似于此的函数:

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;
}

以这种方式:

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

你肯定会找到你的控制权。