3

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

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

详细信息:基本上,我有一个 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() As System.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

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

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

提前致谢!

4

1 回答 1

2

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

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

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

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


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

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
于 2009-12-29T16:55:20.137 回答