取消选中时,ASP.NET CheckBox不会触发CheckedChanged事件

时间:2010-08-11 09:46:41

标签: asp.net viewstate

我在ASP.NET内容表单上有一个CheckBox,如下所示:

<asp:CheckBox runat="server" ID="chkTest" AutoPostBack="true" OnCheckedChanged="chkTest_CheckedChanged" />

在我的代码背后,我有以下方法:

protected void chkTest_CheckedChanged(object sender, EventArgs e)
{
}

当我在浏览器中加载页面并单击CheckBox时,它会被检查,页面会回发,我可以看到chkTest_CheckedChanged被调用。

当我再次单击CheckBox时,它将取消选中,页面会回发,但不会调用chkTest_CheckedChanged

该过程是可重复的,因此一旦取消选中CheckBox,检查它将触发事件。

我在Web.Config中禁用了View State,启用View State会导致此问题消失。当视图状态保持禁用状态时,我可以做些什么才能获得可靠的事件?

更新 如果我在服务器标签上设置Checked="true",那么在取消选中CheckBox时会触发事件,但情况则相反,而不是相反。

更新2: 我已在我的页面中覆盖了OnLoadComplete,并且从那里我可以确认Request.Form["__EVENTTARGET"]已正确设置为我的CheckBox的ID。

10 个答案:

答案 0 :(得分:23)

要触发CheckedChanged事件,请为CheckBox设置以下属性,AutoPostBack属性应该为true,并且应该将默认值设置为false或true。

AutoPostBack="true" Checked="false"

答案 1 :(得分:20)

实现在Checked而非ControlState中存储ViewState属性的自定义CheckBox可能会解决该问题,即使复选框中包含AutoPostBack=false

与ViewState不同,ControlState不能被禁用,并且可用于存储对控件行为至关重要的数据。

我目前没有可视化工作室环境进行测试,但这应该是这样的:

public class MyCheckBox : CheckBox
{
    private bool _checked;

    public override bool Checked { get { return _checked; } set { _checked = value; } }

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        //You must tell the page that you use ControlState.
        Page.RegisterRequiresControlState(this);
    }

    protected override object SaveControlState()
    {
        //You save the base's control state, and add your property.
        object obj = base.SaveControlState();

        return new Pair (obj, _checked);
    }

    protected override void LoadControlState(object state)
    {
        if (state != null)
        {
            //Take the property back.
            Pair p = state as Pair;
            if (p != null)
            {
                base.LoadControlState(p.First);
                _checked = (bool)p.Second;
            }
            else
            {
                base.LoadControlState(state);
            }
        }
    }
}

更多信息here

答案 2 :(得分:8)

它不会触发,因为在禁用viewstate的情况下,服务器代码不知道先前已选中该复选框,因此它不知道状态已更改。至于asp.net知道复选框控件在回发之前未经检查,仍未选中。这也解释了您在设置Checked="true"时看到的反向行为。

答案 3 :(得分:7)

这是一个老帖子,但我必须分享我的简单解决方案,以帮助其他搜索此问题的人。

解决方案很简单:启用AutoPostBack。

        <asp:CheckBox id="checkbox1" runat="server"
                AutoPostBack="True" //<<<<------
                Text="checkbox"
                OnCheckedChanged="knowJobCBOX_CheckedChanged"/>

答案 4 :(得分:6)

我不确定,但我猜我的解决方案仅适用于.NET Framework 4.0:

使用ViewStateMode = "Disabled"禁用EnableViewState="false"的视图状态。除了您可以保存本地视图状态之外,这将警告相同的行为。

因此,在您的复选框上,设置属性ViewStateMode = "Enabled"并解决问题,而不实施自定义复选框。

答案 5 :(得分:1)

我想稍微整理一下,所以我花了一些时间来测试解决方案。

joshb对他解释为什么CheckBox的行为方式是正确的。

由于我不知道自己去年如何,或者即使我做了(我不记得我当时正在检查的是什么),我已经整理了一个简单的解决方案/解决方法。

public class CheckBox2 : CheckBox
{
    protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
    {
        bool isEventTarget = postCollection["__EVENTTARGET"] == UniqueID;
        bool hasChanged = base.LoadPostData(postDataKey, postCollection);
        hasChanged = hasChanged || isEventTarget;
        return hasChanged;
    }
}

如果您现在在页面中注册CheckBox2并使用它来代替标准CheckBox,那么您将获得CheckedChanged事件,因为您已禁用ViewState并启用AutoPostBack。

这种方式的工作方式是允许普通的CheckBox通过验证和更改检查来完成它的工作,但随后执行额外的检查以查看它是否是导致回发的事件的目标。如果它是目标,则返回true以告诉框架引发CheckedChanged事件。

修改 请注意,这只解决了CheckBox上AutoPostBack的问题。如果从其他任何东西(例如按钮)调用PostBack,CheckedChanged事件仍会显示观察到的问题。

答案 6 :(得分:0)

我遇到了同样的问题。我花了很多时间在上面并最终解决了它。

在我的情况下,默认情况下Checkbox被禁用:

<asp:CheckBox ID="chkActive" runat="server" Enabled="false"/>

对于禁用或不可见的控件,未加载ViewState。 因此,请移除Enabled="false"Visible="false",它将按照已经过时的方式运行。当然,不应禁用ViewState

答案 7 :(得分:0)

此外:检查JavaScript控制台中的任何错误

我遇到了与OP描述的完全相同的问题,只是它只发生在Safari中(checkbox在Chrome和Firefox中运行良好)。检查JavaScript控制台后,我发现格式错误的jQuery选择器引发了错误。

在我的情况下,我$('a[id*=lbView')错过了结束]。这在Safari中引发了一个错误,但令人惊讶的是,不是在Chrome中,也不是在Firefox中。

答案 8 :(得分:0)

超级简单的答案是为该一个控件设置ViewState

只需将EnableViewState="true"添加到复选框标记中的AutoPostBack="true"媒体资源。

答案 9 :(得分:0)

CheckBox 的“Checked”属性默认值为false(即取消选中)。因此,当您选中/取消选中 CheckBox 时,它会与 Checked 属性进行比较。

  • 如果它与 Checked 属性不匹配,ASP 会触发 OnCheckedChanged 事件。
  • 如果它与 Checked 属性匹配,则不会触发 OnCheckedChanged 事件。

因此,为了使 ASP 在取消选中时触发 OnCheckedChanged 事件,它必须知道原始值,以便与来自用户的值进行比较并触发事件。

通过在 data-originalValue='<%# Eval("ValueFromCodeBehind") %>' 中添加 asp:CheckBox 属性将能够触发 OnCheckChanged 事件,因为 ASP 现在能够知道其先前的值。因此,当我们更改它时,即使我们取消选中,ASP 也会触发 OnCheckChanged 事件。