Обработчик событий пользовательского управления сервером asp.NET не запускается при второй обратной передаче

Я разрабатываю настраиваемый серверный элемент управления в Asp.NET (.NET 3.5), который наследует класс CompositeControl. В моем элементе управления я переопределяю метод CreateChildControls() для создания смеси серверных элементов управления html и Asp.NET. Некоторые из добавленных элементов управления Asp.NET - это LinkButtons (каждый из которых имеет свой Command обработчик событий, установленный на метод в моем элементе управления). Я обнаружил, что при первом щелчке по одному из этих LinkButton запускается обратная передача, и метод обработчика событий запускается правильно. Внутри этого обработчика событий метод CreateChildControls () явно вызывается для восстановления элемента управления в ответ на обратную передачу. Затем я обнаружил, что последующие щелчки обратных передач LinkButtons не приводят к возникновению метода обработчика событий.

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

Упрощенная версия моего класса управления показана ниже:

public class SearchResults : CompositeControl
{
    private int PageIndex = 0;

    protected override void CreateChildControls()
    {
            //do stuff here e.g.
            LinkButton prevLink = new LinkButton();
            prevLink.Text = "< Prev";
            prevLink.CommandArgument = (PageIndex - 1).ToString();
            prevLink.Command += new CommandEventHandler(PagerLinkCommand);
            this.Controls.Add(prevLink);
    }

    protected void PagerLinkCommand(object sender, CommandEventArgs e)
    {
        PageIndex = int.Parse(e.CommandArgument.ToString());
        CreateChildControls();
    }
}

РЕДАКТИРОВАТЬ Проблема здесь была вызвана тем фактом, что элемент управления используется на сайте Sitecore, и я забыл зарегистрировать тип элемента управления в файле web.config с записью <typesThatShouldNotBeExpanded>. Эта запись используется для предотвращения того, чтобы события серверных элементов управления были искажены Sitecore - это может вызвать аналогичные проблемы для стандартных серверных элементов управления, таких как ListView, GridView и Repeater и т. Д. Мой web.config был изменен, как показано ниже:

  <typesThatShouldNotBeExpanded>
    <type>System.Web.UI.WebControls.Repeater</type>
    <type>System.Web.UI.WebControls.DataList</type>
    <type>System.Web.UI.WebControls.GridView</type>
    <type>MyNamespace.MyCustomControl</type> <!-- This is the bit I added -->
  </typesThatShouldNotBeExpanded>

person Matthew Dresser    schedule 13.05.2011    source источник
comment
Базовый класс должен вызывать за вас CreateChildControls () - попробуйте удалить его.   -  person IrishChieftain    schedule 13.05.2011


Ответы (4)


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

LinkButton prevLink = new LinkButton();
prevLink.ID = "prevLink";
person James McCormack    schedule 13.05.2011
comment
вы сделали это для всех сгенерированных элементов управления в методе CreateChildControls ()? В частности, элементы управления, в которые вложен LinkButton. - person James McCormack; 13.05.2011
comment
Я нашел эту статью v полезной: singingeels.com/Articles/ - person James McCormack; 13.05.2011

Извинения ... это не полный ответ, но предложение по отладке слишком длинное для комментария:

Сохраните в браузере HTML-копию своей страницы для начальной загрузки, обратной загрузки и второй обратной передачи. Затем сравните файлы, используя свой любимый инструмент сравнения. Устранение очевидных различий, таких как результаты поиска и т. Д. Это может помочь вам точно определить любые проблемы с идентификаторами элементов управления, отсутствующими элементами управления и т. Д.

Двумя абсолютными ключами к успешным динамически создаваемым элементам управления являются:
1) их создание в нужное время в течение жизненного цикла страницы;
2) воссоздание ТОЧНОЙ ИДЕАЛЬНОЙ иерархии элементов управления (включая идентификаторы) при обратной передаче.

person Bryan    schedule 17.05.2011

Чтобы получить правильное дерево элементов управления, переопределите свойство Controls и вызовите EnsureChildControls, а также вызовите EnsureChildControls, а не CreateChildControls внутри PagerLinkCommand.

    /// <summary>
    /// Gets controls.
    /// </summary>
    public override ControlCollection Controls
    {
        get
        {
            EnsureChildControls();
            return base.Controls;
        }
    }

    /// <summary>
    /// Create child controls.
    /// </summary>
    protected override void CreateChildControls()
    {
        this.Controls.Clear();
        //do stuff here e.g.
        LinkButton prevLink = new LinkButton();
        prevLink.Text = "< Prev";
        prevLink.CommandArgument = (PageIndex - 1).ToString();
        prevLink.Command += new CommandEventHandler(PagerLinkCommand);
        this.Controls.Add(prevLink);
    }

    protected void PagerLinkCommand(object sender, CommandEventArgs e)
    {
      PageIndex = int.Parse(e.CommandArgument.ToString());
      EnsureChildControls();
    }        
person khorvat    schedule 13.05.2011
comment
К сожалению, этого не происходит. CreateChildControls () теперь не вызывается после PagerLinkCommand (). - person Matthew Dresser; 13.05.2011
comment
не забудьте вызов base.CreateChildControls () внутри CreateChildControls () - person James McCormack; 13.05.2011

Причина такого поведения была связана не с самим серверным элементом управления, а с Sitecore. Чтобы Sitecore не мешал обратным передачам управления сервером, необходимо добавить запись в разделе typesThatShouldNotBeExpanded в файле web.config, как показано ниже.

<typesThatShouldNotBeExpanded>
  <type>System.Web.UI.WebControls.Repeater</type>
  <type>System.Web.UI.WebControls.DataList</type>
  <type>System.Web.UI.WebControls.GridView</type>
  <type>MyNamespace.MyCustomControl</type> <!-- This is the bit I added -->
</typesThatShouldNotBeExpanded>
person Matthew Dresser    schedule 06.07.2011