Listview не полностью обновляется в databind () после обратной передачи - PullRequest
5 голосов
/ 04 мая 2009

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

Мой источник данных в виде списка привязан к списку элементов, который хранится в состоянии сеанса страницы. Это сделано намеренно, частично для тайм-аута устаревших просмотров, поскольку данные просматривают несколько пользователей. В простой курортной операции сортировка выполняется на странице с помощью javascript, а порядок данных списка / сеанса синхронизируется с помощью обратных вызовов. Обратный вызов также проверяет уровни разрешений. При выполнении более сложной операции курорта javascript на странице выполняет обратную передачу на страницу для обработки логики сортировки. Список / Сеанс обновляется как при обратном вызове, затем элемент управления просмотра списка возвращается к данным. Страница снова загружается, и в строках отображается новый порядок. Нет проблем, верно?

Проблема в том, что некоторые элементов в просмотре списка не изменяют значение в соответствии с новым порядком. Хотя гиперссылки и текст, обрабатываемый на странице (например, <% # Eval ("ProjectAbbrev")%>), обновляются соответствующим образом, флажки, литералы и раскрывающиеся списки, значения которых установлены с помощью метода события OnItemDataBound, не сохраняются - они остаются «заморожен» на месте, хотя пошаговое выполнение кода показывает, что метод выполняется во время обратной передачи, и что элементам управления СЛЕДУЕТ установить их новые значения. Если я пойду и укрою список вручную, скажем, половина исходного размера, конечно же, будут заполнены только те элементы, но флажки и тому подобное сохранят свои исходные значения.

Итак, мой вопрос: почему эти элементы не обновляются вместе с остальными элементами управления списком просмотра на обратной передаче? У меня такое ощущение, что я либо неправильно понимаю жизненный цикл страницы в ASP.NET, либо столкнулся с какой-то ошибкой.

На данный момент я думаю, что мне придется перенести более сложную операцию сортировки на страницу в javascript, но это будет довольно сложно, и я хотел бы избежать этого, если это возможно. <Ч /> ОБНОВЛЕНИЕ: я попытался установить EnableViewState в false, и это не исправляет это. Я не мог использовать эту тактику в любом случае, потому что другие части страницы (сохранить) полагаются на чтение состояния просмотра в конце. <Ч /> ОБНОВЛЕНИЕ: я предоставляю некоторые фрагменты кода в надежде, что они могут пролить свет на эту проблему:

Страница: элемент HyperLink будет корректно обновляться после обратной передачи, но CheckBox, значение которого назначено в методе OnQueueRepeater_ItemDataBound, останется прежним.

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TextProcessorProjects.ascx.cs" Inherits="ETD.UI.Controls.TextProcessorProjects" %>

<asp:ListView ID="QueueListView" runat="server" OnItemDataBound="OnQueueRepeater_ItemDataBound">
 <ItemTemplate>
  <tr>
   <td><asp:HyperLink runat="server" ID="ProjectIDLink"><%# Eval("ProjectAbbrev") %></asp:HyperLink></td>
   <td><asp:CheckBox runat="server" ID="ScannedCheckBox" BorderStyle="None" /></td>
  </tr>
 </ItemTemplate>
</asp:ListView>

Код сзади: при обратной передаче выполняется следующий код:

protected List<Book> QueueDataItems
{
 get { return (List<Book>)Session["Queue"]; }
 set { Session["Queue"] = value; }
}

else if (IsPostBack && !Page.IsCallback)
{
 // resort QueueDataItems List appropriately
 ResortQueue(Request.Params) 
 // rebind
 QueueListView.DataSource = QueueDataItems;
 QueueListView.DataBind();
}

protected void OnQueueRepeater_ItemDataBound(object sender, ListViewItemEventArgs e)
{
 // ...
 // ... other controls set
 CheckBox scannedCheckBox = e.Item.FindControl("ScannedCheckBox") as CheckBox;
 scannedCheckBox.Checked = book.Scanned;
}

ОБНОВЛЕНИЕ: Я перестал работать над этим и перенес свою логику сортировки на клиентскую сторону с помощью JavaScript. Если у кого-то есть какие-либо идеи относительно того, почему происходит такое странное поведение, мне все равно было бы очень интересно услышать их!

Ответы [ 7 ]

6 голосов
/ 14 июля 2009

Из интереса, на каком месте страницы вы привязываете данные? Page_Load?

Попробуйте на OnPreRender - может помочь.

2 голосов
/ 21 июля 2009

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

2 голосов
/ 04 мая 2009

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

0 голосов
/ 16 июля 2009

Не уверен, поможет ли это, замените <% # Eval ("ProjectAbbrev")%> на Hyperlink.Text, назначенный в методе OnQueueRepeater_ItemDataBound, и посмотрите, правильно ли заполнены все строки.

Возможно, это не решит вашу проблему, но будет интересно узнать результат.

0 голосов
/ 23 июня 2009

Является ли элемент управления флажком ReadOnly = true или Enabled = false?

У меня были проблемы с элементами управления с одним из этих свойств, установленным, как указано выше, без обновления, независимо от того, как я пытаюсь обработать элемент управления в коде. Я бы подумал, что отключение состояния представления также обойдёт эту маленькую «функцию» ASP.NET, но оно того стоит.

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

0 голосов
/ 21 мая 2009

Есть ли вероятность, что это может быть проблемой кеширования? Я столкнулся с подобной проблемой, используя просмотр списка с источником XMLDatasource. Я пытался отключить все viewstate. Я бы связал просмотр списка в коде и использовал XPath, чтобы выписать все это на экран на моей странице aspx. Это было использовано при поиске .... в следующий раз, когда я выполнял поиск, новая информация не появилась. Причина в том, что в XMLDatasource по умолчанию включено кэширование. В моем случае я каждый раз ударил по БД и не нуждался в кешировании. Я отключил кеширование на источнике данных, и все мои проблемы были исправлены.

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

0 голосов
/ 07 мая 2009

Возможно, по какой-то причине ваш QueueListView перепривязывается.

Попробуйте сбросить значение DataSource после DataBind (), чтобы увидеть, что происходит

QueueListView.DataBind();
QueueListView.DataSource = null;
...