在页面回发上阅读动态CheckBox的'Checked'属性

时间:2009-12-29 16:37:51

标签: vb.net dynamic checkbox postback pageload

为这篇冗长的帖子提前道歉,但我正在构建一个.NET页面遇到一些麻烦。

结束问题:如何在Page_Load子例程中检查动态创建的复选框的“已检查”属性?

DETAILS:基本上,我有一个VB.NET页面,它根据用户选择的数字动态创建一些表格行。因此,例如,如果用户从下拉列表中选择“3”,则页面回发并创建三个表行。每行包含几个文本框,一个下拉列表和一个复选框(这些都是.NET表单控件而不是纯HTML控件,我应该指出)。

通常,用户会在表单控件中输入一些详细信息,然后单击“提交”按钮,之后页面将遍历每一行,并将数据插入到SQL Server表中。

但是如果用户勾选该行的复选框,则表示该页面将忽略该行,并且当用户单击“提交”时,不会将该行数据插入数据库。

这很好用,但是有问题。如果用户单击“提交”并且表单控件中输入的某些值无效(例如,用户未输入其名称),则页面将不提交数据,而是显示错误向用户通知他们需要改变的值。但是,如果用户创建了三行,例如,但是决定“忽略”第三行(通过勾选复选框),那么当页面回发时,找到一些无效的条目,并将表单重新显示给用户以允许它们为了纠正任何错误,我宁愿页面完全没有呈现第三行。毕竟,他们原本选择创建三行,但后来决定只需要两行。因此,重新创建第三行是有道理的。

首先,我在 Page_Load 子例程中使用了与以下内容类似的代码:

If objCheckbox.Checked = False
   ' Render the row, and recreate the dynamic controls '
Else
   ' Dont render the row or any of the controls '
End If

但似乎发生的事情是 objCheckbox.Checked 总是返回 False ,即使勾选了复选框也是如此。加载页面后,表格行再次呈现,复选框中出现勾号,因此它不像回发时丢失的值。但在此我检查是否勾选了复选框,它总是返回 False ,呈现用户不需要的表格行。

有谁知道如何解决这个问题?我已经阅读了很多关于.NET ViewState和页面生命周期的文章,但我还没有找到有效的解决方案。我只需要能够在重新创建一些动态控件之前检查是否勾选了复选框。

我尝试了这个使用ViewState的替代代码,但无济于事:

If objIgnoreCheckbox.ViewState("Checked") = False Then
   ' Render the row, and recreate the dynamic controls '
Else
   ' Dont render the row or any of the controls '
End If

执行此操作时,我收到以下错误:

'System.Web.UI.Control.Protected Overridable ReadOnly Property ViewState()AsSystem.Web.UI.StateBag'在此上下文中无法访问,因为它是“受保护的”。

所以我尝试创建一个继承自Checkbox的自定义类,并尝试覆盖ViewState属性以使其公开,以便可以从中读取:

Public Class CheckboxControl

    ' Inherits all Checkbox properties and methods '
    Inherits Checkbox

    ' Create the public ViewState property '        
    Public Overrides ReadOnly Property ViewState As StateBag

        Get
            Dim objChecked As Object = ViewState("Checked")
            If Not (IsNothing(objChecked)) Then
                Return objChecked
            End If
        End Get

    End Property

End Class

但后来我基本上发现你不能用公共成员覆盖受保护的成员。我在创建新课程方面的经验很少,所以我很难过。

所以,如果有人能告诉我如何检查这个复选框,我会永远感激不尽!我花了整整一天的时间试图解决问题,但没有运气!

提前致谢!

1 个答案:

答案 0 :(得分:2)

对于静态控件,控件的视图状态将在Page_Init中恢复,这在Page_Load之前发生,因此它们在Page_Load中包含正确的值。动态控件是在Page_Load中创建的,因此Page_Load中的视图状态不正确,并且会在 Page_Load之后恢复,但在调用之前事件处理程序。 MSDN says:

  

在运行Page_Load事件之后,但在调用控件事件处理方法之前,剩余的视图状态信息将加载到动态创建的控件中。

这就是Checked返回false的原因,以及为什么更改CheckBox.ViewState的可见性无法解决您的问题。

解决方案(未经测试,但我认为它应该可行):在Page_Load中创建所有控件(甚至是那些您不想显示的控件) 。将CheckedChanged上的事件处理程序附加到CheckBoxes(Page_Load)。在Page_Load完成后,ASP.NET将恢复新创建的控件的视图状态(这就是为什么在Page_Load中创建相同的控件很重要,这样ASP.NET才能正确将视图状态映射到控件),ASP.NET将为已更改的CheckBox调用事件处理程序。在那里,您可以删除不想显示的行。


这是添加事件处理程序的方法

AddHandler objCheckbox.CheckedChanged, AddressOf MyCheckedChangedFunction

这个函数看起来像这样:

Function MyCheckedChangedFunction(sender As Object, e As EventArgs)
    Dim objCheckbox = DirectCast(sender, CheckBox)

    ... access objCheckbox.Changed and do something useful here ...
End Function