ItemCommand не срабатывает при первом нажатии в Repeater или GridView - PullRequest
2 голосов
/ 27 октября 2010

Это сводит меня с ума уже 2 дня - надеюсь, кто-то уже видел это раньше.

У меня есть проблема, когда первый щелчок элемента управления в представлении повторителя или сетки не запускает событие ItemCommand, все последующие клики работают.Элементы управления загружаются в заполнитель на Base.aspx следующим образом:

    private void LoadUserControl()
    {
        string controlPath = LastLoadedControl;

        if (!string.IsNullOrEmpty(controlPath))
        {
            ph.Controls.Clear();

            UserControl uc = (UserControl)LoadControl(controlPath);
            ph.Controls.Add(uc);
        }

    }

Мне интересно, является ли это проблемой состояния представления, и в каких событиях страницы я должен использовать DataBind ().Я экспериментировал с привязкой данных в различных событиях страницы, предоставляя возможность просмотра состояния на странице и управления без изменения результата.

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

<ItemTemplate>
       <asp:RadioButton ID="rbEnable" GroupName="MyGroup" runat="server" Text="Enabled" Checked="<%# ((EducateMe.BaseTypes.AbstractLink)Container.DataItem).IsActive == true %>" />
       <asp:RadioButton ID="rbDisable" runat="server" GroupName="MyGroup" Text="Disabled" Checked="<%# ((EducateMe.BaseTypes.AbstractLink)Container.DataItem).IsActive != true %>" />
       <asp:Button ID="btnEnable" runat="server" CommandArgument="<% # Container.DataItemIndex %>" CommandName="Enable" ToolTip="Enable" Text="Save" />
       <asp:Button ID="btnDisable" runat="server" CommandArgument="<% # Container.DataItemIndex %>" Visible="false" CommandName="Disable" ToolTip="Disable" Text="Disable" />
    </ItemTemplate>

Некоторая дополнительная информация, которая можетбыть актуальным:

То, что я заметил, - это событие Page_Load пользовательского элемента управления, где я перепривязываю элемент управления.Вероятно, это и есть причина того, что состояние элемента управления переписывается, но если я добавлю if (! IsPostback) в эту область в ascx, эта секция кода вообще не сработает, как на странице aspx.Я думаю, это будет правильный раздел для повторного связывания элемента управления.

Ответы [ 3 ]

8 голосов
/ 29 октября 2010

MikeW,
После нескольких часов возни с этим я нашел корень вашей проблемы.
Это не имеет ничего общего с ретранслятором или видом сетки.
Это просто динамическийпроблема контроля над обратной связью.

Чтобы решить вашу проблему:
Удивительно, но в вашем коде отсутствует только одна строка.
Прямо при загрузке элемента управления присвойте его идентификатору что-то вроде этого:

UserControl uc = (UserControl)LoadControl(controlPath);
uc.ID = "mycontrol";
ph.Controls.Add(uc);

Таким образом, когда вы отправляете сообщение, страница знает, какой элемент управления какой.

Чтобы объяснить это проще, давайте упростим проблему.
Вот сценарий нажатия кнопки два раза подряд, который динамически создает другую кнопку:

  • Создание одной кнопкиButton1, которая при нажатии будет загружать другую кнопку динамически, Button2.Предположим, что действие Button2 так же просто, как отображение текущего времени.
  • Теперь нажмите Button1.
  • Чтобы сохранить Button2, вы должны использовать ViewState, чтобы сообщить странице, что есть динамический элемент управления.Как и вы, мы можем запомнить путь элемента управления или имя его класса.
  • Прямо, когда страница отправляется обратно, в Page_Load мы смотрим на ViewState, чтобы увидеть, что есть элемент управления, который мы пытаемся сохранить, поэтому мы загружаем его прямо там (это эквивалентноваша LoadUserControl() функция выше).
  • К настоящему времени Button2 видна, и при нажатии она выполнит свои действия очень хорошо.
  • Не нажимайте Button2, просто снова нажмите Button1 (что эквивалентно переключению междудва разных динамических элемента управления).
  • Угадайте, что происходит сейчас: Page_Load загрузит Button2 из ViewState.И событие Click Button1 загрузит ДРУГОЙ экземпляр Button2 после очистки заполнителя.
  • Так как вы не присвоили ему идентификатор, он назначит себе один в UniqueID, и у этих двух Button2 будет что-то вроде ctl02 и ctl03
  • Теперь нажмите кнопку 2.
  • Вы скажете: «Хорошо, мы перезаписываем старую».Да, но не без идентификатора.
  • Поскольку вы не дали ему идентификатор для идентификации на обратной передаче, он будет использовать UniqueID, который генерируется последовательно.
  • Теперь страница ищет ctl03 , которого не существует, поэтому Click не срабатывает.
  • Но теперь у нас естьсовершенно новая Button2, с UniqueID ctl02 .
  • Нажатие на эту новую Button2 будет работать просто отлично, потому что на обратной передаче, это единственная кнопка Button2, поэтому по совпадению она будет иметь UniqueID ctl02 .

Итак, как назначение идентификатора заставляет его работать?
Таким образом, каждый новый сгенерированный элемент управления будет иметь одинаковый идентификатор, поэтому при обратной передаче он может найти то, что ищет,оно было сгенерировано в Page_Load или в событии Click другой кнопки.

Надеюсь, это объясняет, почему это работает, но, насколько вам интересно, просто присвойте ему идентификатор, и все будет хорошо.
Я подумал, что было бы интересно поделиться механизмом, стоящим за ним, и почемудело.=)

1 голос
/ 13 марта 2012

Я понял это, но я не понимаю, почему.
Оригинальный код был:

Me.rpAgreementContractors.DataSource = dtContractors
Me.rpAgreementContractors.DataBind()
Me.tblAgreementContractors.Visible = True
Me.phDataPane.Controls.Add(Me.tblAgreementContractors)

Я изменил его, чтобы сделать таблицу видимой и добавить ее в заполнитель, прежде чем установить источник данных и связать его. Проблема решена.

Me.tblAgreementContractors.Visible = True
Me.phDataPane.Controls.Add(Me.tblAgreementContractors)
Me.rpAgreementContractors.DataSource = dtContractors
Me.rpAgreementContractors.DataBind()
0 голосов
/ 27 октября 2010

Я не уверен насчет остальной части вашего кода, но обычно, когда я вижу проблему «первое действие ведет себя иначе, чем последующие действия», как это потому, что я поместил что-то не в ту сторону раздела IsPostBack.

Например, я нахожу себя обязательным, когда это обратная передача, поэтому мои события не работают до второй обратной передачи, потому что первая обратная передача происходит, когда они родились, и начальная загрузка страницы никогда не выполняла эту часть.

Я думаю, вы на правильном пути;убедитесь, что вы связываете и проводите свои мероприятия в нужный момент.

...