Почему несвязанные (autopostback) методы вызываются, когда вызывается метод Autopback Asp.Net ListBox? - PullRequest
5 голосов
/ 14 ноября 2009

Я уверен, что это просто, но это сводит меня с ума.

У меня есть ListBox на моей странице для отображения исполнителей, который вызывает метод при изменении индекса, и кнопка, которая загружает исполнителя из этого списка на другой странице при нажатии:

<asp:ListBox ID="lbArtists" runat="server" Rows="1" AutoPostBack="true" OnSelectedIndexChanged="ShowArtistsWorks" />

<asp:Button ID="btnEditArtist" runat="server" Text="Edit the artist" OnClick="LoadArtist" />

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

<asp:ListBox ID="lbLinks" runat="server" Rows="1" AutoPostBack="true" OnSelectedIndexChanged="LoadLink" />

Проблема в том, что когда я вызываю ShowArtistsWorks(), нажимая btnEditArtist, также вызывается метод LoadLink(). Почему это происходит? Почему это вызывается, если я не изменил индекс в lbLinks ListBox? Это не должно приближаться к этому методу.

РЕДАКТИРОВАТЬ: (релевантно) Методы выделения кода (

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack){
        GetArtists(); // populates artists listbox
        GetLinks(); // populates links listbox
    }
}

protected void LoadArtist(object sender, EventArgs e){
    if (lbArtists.SelectedValue != "")
        Response.Redirect("Artist.aspx?id=" + lbArtists.SelectedValue);
}

protected void LoadLink(object sender, EventArgs e)
{
    if (lbLinks.SelectedValue != "")
        Response.Redirect("Link.aspx?id=" + lbLinks.SelectedValue);
}

РЕДАКТИРОВАТЬ # 2: Я мог бы легко исправить это в отдельных методах, чтобы они не происходили, когда они не должны, но я хочу понять, почему методы, которые я не вызываю, и который вызывается только из одного места, вызывается непреднамеренно.

ПРИНЯТО ОТВЕТ: Несмотря на то, что Бун (теперь CRice) пришел первым с объяснением и решением, я решил принять более подробное объяснение Джеффа, потому что это было то, что я хотел, более глубокий анализ , Спасибо всем, кто ответил.

Ответы [ 7 ]

2 голосов
/ 18 ноября 2009

События изменений возникают при каждой обратной передаче, для которой они актуальны - как описано в разделе MSDN " Модель событий управления веб-сервером ASP.NET ."

Изменение событий в элементах управления HTML-сервера и элементы управления веб-сервера, такие как Контроль TextBox, не сразу вызвать пост. Вместо этого они подняты в следующий раз, когда появится сообщение .

Когда пользователи нажимают кнопку «Редактировать исполнителя», ASP.NET думает, что lbLinks.SelectedIndex изменился, и вызывает свой обработчик SelectedIndexChanged.

Причина ASP.NET считает, что индекс изменился: при первой загрузке страницы lbLinks не имеет выбранного индекса (или значения), если вы не укажете иначе, явно установив его , Пока вы не сделаете это, выбранный индекс равен -1, а его выбранное значение - пустая строка. Выбранное значение (в данном случае пустая строка) записывается для просмотра состояния при отображении страницы , чтобы ASP.NET мог определить, изменилось ли значение в обратных передачах .

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

При следующей публикации обратно элемент HTML <select> lbLinks имеет непустое значение и отправляется как часть данных публикации. Посмотрите на Request.Form["lbLinks"], и вы увидите, что оно равно lbLinks.Items[0].Value.

ASP.NET отображает опубликованное значение в lbLinks.SelectedValue, но также знает, что выбранное значение раньше было пустой строкой - оно получает старое значение из состояния просмотра. Поскольку эти два значения различны, процесс вызывает событие изменения выбранного индекса элемента управления, вызывая нежелательное поведение, которое вы наблюдали.

Как подсказал Бун , решение состоит в том, чтобы всегда явно устанавливать SelectedIndex для всех ваших ListBox элементов управления, когда вы используете событие OnSelectedIndexChanged, даже если вы просто устанавливаете индекс до нуля.

(Параметр AutoPostBack представляет собой несвязанную красную сельдь. Если вы удалите ее из обоих списков, их события OnSelectedIndexChanged будут срабатывать каждый раз, когда вы нажимаете кнопку.)

1 голос
/ 18 ноября 2009

Согласно странице, оба списка изменились. Это был selectedIndex -1, тогда, когда страница загружается, они оба перейдут к выбранному индексу 0, возможно из-за способа, которым вы назначаете им данные. Поэтому, когда происходит обратная передача, имеет смысл запускать оба метода, поскольку их выбранный индекс фактически изменился.

Посмотрите, устранит ли ваша проблема следующее. Установите выбранный индекс как ноль:

if (!IsPostBack){  
    GetArtists(); // populates artists listbox  
    GetLinks(); // populates links listbox

    lbArtists.SelectedIndex = 0;
    lbLinks.SelectedIndex = 0;
} 
0 голосов
/ 19 ноября 2009

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

0 голосов
/ 18 ноября 2009

Проблема в ваших объявлениях AutoPostBack = "true". Я не знаю точной причины, если кто-то еще хотел бы уточнить, но когда несколько элементов управления на странице имеют AutoPostBack = "true", все события на стороне сервера запускаются при отправке обратно на сервер.

EDIT Я предполагаю, что по какой-то причине, возможно, связанной с состоянием просмотра, SelectedIndexChanged оценивается как true для обоих элементов управления при обратной передаче.

0 голосов
/ 14 ноября 2009

Попробуйте посмотреть стек вызовов и выясните, почему вызывается несвязанный метод.

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

Стек вызовов должен помочь вам определить причину, для начала.

0 голосов
/ 14 ноября 2009

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

0 голосов
/ 14 ноября 2009

Вы уверены, что не изменили индекс в другом списке? Возможно, вы повторно связываете это поле со списком, возможно, потому что этот код выполняется в пост-пакете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...