Подтвердить что ты не робот

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

Процесс повторяется, поэтому, если CheckBox не отмечен, проверка его приведет к срабатыванию события.

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

Update: Если я установил Checked="true" на теге сервера, ситуация будет обращена вспять при запуске события при снятии флажка CheckBox, но не наоборот.

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

4b9b3361

Ответ 1

Реализация этой особой CheckBox, которая сохраняет свойство 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 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);
            }
        }
    }
}

подробнее здесь.

Ответ 2

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

AutoPostBack="true" Checked="false"

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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

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

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

Ответ 6

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

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.

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

Ответ 7

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

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

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

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

Ответ 8

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

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

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

Ответ 9

Самый простой ответ - установить ViewState для этого элемента управления.

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