ASP.NET CheckBox не запускает событие CheckedChanged при снятии флажка

У меня есть CheckBox в форме содержимого ASP.NET, например:

<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 не вызывается.

Процесс повторяется, поэтому, если флажок снят, проверка вызовет событие.

У меня состояние просмотра отключено в Web.Config, включение состояния просмотра приводит к исчезновению этой проблемы. Что я могу сделать, чтобы событие срабатывало надежно, когда состояние просмотра остается отключенным?

Обновление: если я установил Checked="true" в теге сервера, ситуация изменится на обратную, при снятии флажка CheckBox срабатывает событие, но не наоборот.

Обновление 2: я переопределил OnLoadComplete на своей странице и оттуда могу подтвердить, что Request.Form["__EVENTTARGET"] правильно установлен на идентификатор моего флажка.


person Matt    schedule 11.08.2010    source источник
comment
такое случается и со мной, почему это происходит? какая-нибудь информация? какой-нибудь свет в конце этого туннеля (он меня не заденет)?   -  person Ayyash    schedule 23.09.2010
comment
это поможет, если вы можете опубликовать код своего события Page_Load   -  person Waqas    schedule 05.08.2011
comment
В событии Page_Load ничего нет. Весь код в оригинальном посте.   -  person Matt    schedule 06.08.2011


Ответы (9)


Реализация настраиваемого флажка, в котором свойство Checked хранится в ControlState, а не в ViewState, вероятно, решит эту проблему, даже если флажок установлен 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);
            }
        }
    }
}

Дополнительная информация здесь.

person Johnny5    schedule 10.08.2011
comment
Спасибо, это работает как по волшебству. Я не могу поверить в то, что все время, что я работаю в .Net, я никогда не сталкивался с этой проблемой до сих пор. Это также работает с динамически создаваемыми флажками, просто зарегистрируйте их как экземпляры MyCheckBox вместо стандартных, и все готово. - person pharophy; 10.12.2012
comment
Большое спасибо. Почему флажки не работают из коробки, я не знаю. - person Duncan Howe; 12.08.2013

Чтобы запустить событие CheckedChanged, установите следующие свойства для CheckBox, свойство AutoPostBack должно иметь значение true, а значение по умолчанию должно иметь значение false или true.

AutoPostBack="true" Checked="false"
person Able Alias    schedule 28.10.2013
comment
Принятый ответ - излишек для этой простой проблемы. Этот ответ должен был быть принятым. - person Matheus Rocha; 23.04.2018
comment
Я не могу больше согласиться с @MatheusRocha. Я был очень разочарован принятым ответом и определенно не собирался его пробовать. Этот ответ действительно спас меня от изменения дизайна. - person Unbound; 04.05.2018
comment
Хороший человек! Я согласен, что это должен быть принятый ответ. У меня конечно сработало! - person Andrew Fielden; 10.08.2018
comment
Это должен быть принятый ответ для данной ситуации. - person John Waclawski; 11.04.2019

Он не срабатывает, потому что при отключенном состоянии просмотра код сервера не знает, что флажок был ранее установлен, поэтому он не знает, что состояние изменилось. Насколько известно asp.net, флажок не был установлен перед обратной передачей и все еще не установлен. Это также объясняет обратное поведение, которое вы видите при установке Checked="true".

person joshb    schedule 05.08.2011
comment
Я возвращаюсь к этому через год, поэтому я не могу точно вспомнить, о чем я тогда думал, но вы правы, жизненный цикл страницы действительно вызывает такой эффект. Я думаю, что, возможно, я ожидал, что, поскольку __EVENTTARGET был установлен для моего флажка, ASP.NET может быть достаточно умен, чтобы понять, что это изменилось. - person Matt; 06.08.2011

Я не уверен, но полагаю, что мое решение работает только для .NET Framework 4.0:

Используйте ViewStateMode = "Disabled", чтобы отключить состояние просмотра, установленное для EnableViewState="false". Это предупредит такое же поведение, за исключением того, что вы можете сохранить локальное состояние просмотра.

Итак, установите для флажка атрибут ViewStateMode = "Enabled", и проблема будет решена без использования настраиваемого флажка.

person Cristian Nicoleta    schedule 27.03.2012

Это старый пост, но мне пришлось поделиться своим простым решением, чтобы помочь другим, кто искал эту проблему.

Решение простое: Включите AutoPostBack.

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

Я хотел немного привести в порядок вещи, поэтому я просто потратил немного времени на тестирование решения для этого.

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.

Изменить: Обратите внимание, что это решает проблему только для AutoPostBack на CheckBox. Если PostBack вызывается из чего-либо еще (например, из кнопки), событие CheckedChanged по-прежнему демонстрирует наблюдаемую проблему.

person Matt    schedule 06.08.2011
comment
Может быть полезно в случае, когда LoadPostData не вызывает stackoverflow.com/questions/3211200/ - person sll; 31.03.2013

У меня такая же проблема. Я потратил на это много времени и наконец решил.

В моем случае Checkbox был отключен по умолчанию:

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

Оказывается, ViewState не загружается для отключенных или невидимых элементов управления. Так что удалите Enabled="false" или Visible="false", и он будет работать, как ожидалось. И, конечно же, ViewState нельзя отключать.

person algreat    schedule 18.02.2014

Дополнительно: Проверьте наличие ошибок в консоли JavaScript.

У меня возникла та же проблема, что описана OP, за исключением того, что это произошло только в Safari (checkbox отлично работал в Chrome и Firefox). Изучив консоль JavaScript, я обнаружил ошибку, вызванную искаженным селектором jQuery.

В моем случае у меня было $('a[id*=lbView'), в котором отсутствовал закрывающий ]. Это привело к ошибке в Safari, но, что удивительно, не в Chrome или Firefox.

person Mr.Z    schedule 22.12.2015

Очень простой ответ - включить ViewState для этого элемента управления.

Просто добавьте EnableViewState="true" к свойству AutoPostBack="true" в теге флажка.

person Community    schedule 07.01.2016