2010-06-09 3 views
5

В пользовательском элементе управления у меня есть ретранслятор внутри UpdatePanel (этот идентификатор отображается внутри модуля ModalPopupExtender. Ретранслятор представляет собой привязку данных, используя список массивов объектов MyDTO. каждый элемент в списке. После привязки ImageURL и CommandArgument установлены.UpdatePanel, Repeater, DataBinding Problem

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

У любого человека есть проблемы с кодом?

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

ASCX

<asp:UpdatePanel ID="ViewDataDetail" runat="server" ChildrenAsTriggers="true"> 
    <Triggers> 
     <asp:PostBackTrigger ControlID="ViewDataCloseButton" /> 
     <asp:AsyncPostBackTrigger ControlID="DataRepeater" /> 
    </Triggers> 
    <ContentTemplate> 
     <table width="100%" id="DataResults"> 
     <asp:Repeater ID="DataRepeater" runat="server" OnItemCommand="DataRepeater_ItemCommand" OnItemDataBound="DataRepeater_ItemDataBound"> 
     <HeaderTemplate> 
      <tr> 
      <th><b>Name</b></th> 
      <th><b>&nbsp;</b></th> 
      </tr> 
     </HeaderTemplate> 
      <ItemTemplate> 
      <tr> 
       <td> 
       <b><%#((MyDTO)Container.DataItem).Name%></b> 
       </td> 
       <td> 
       <asp:ImageButton CausesValidation="false" ID="DeleteData" CommandName="Delete" runat="server" /> 
       <asp:ImageButton CausesValidation="false" ID="RunData" CommandName="Run" runat="server" /> 
       </td> 
      </tr> 
      <tr> 
       <td colspan="2"> 
       <table> 
        <tr> 
        <td>Description : </td> 
        <td><%#((MyDTO)Container.DataItem).Description%></td> 
        </tr> 
        <tr> 
        <td>Search Text : </td> 
        <td><%#((MyDTO)Container.DataItem).Text%></td> 
        </tr> 
       </table> 
       </td> 
      </tr> 
      </ItemTemplate> 
     </asp:Repeater> 
     </table> 
    </ContentTemplate> 
</asp:UpdatePanel> 

Code-Behind

public DeleteData DeleteDataDelegate; 
    public RetrieveData PopulateDataDelegate; 
    public delegate ArrayList RetrieveData(); 
    public delegate void DeleteData(String sData); 


protected void Page_Load(object sender, EventArgs e) 
    { 
     //load the initial data.. 
     if (!Page.IsPostBack) 
     { 
      if (PopulateDataDelegate != null) 
      { 
       this.DataRepeater.DataSource = this.PopulateDataDelegate(); 
       this.DataRepeater.DataBind(); 
      } 
     } 
    } 

    protected void DataRepeater_ItemCommand(object source, RepeaterCommandEventArgs e) 
    { 
     if (e.CommandName == "Delete") 
     { 
      if (DeleteDataDelegate != null) 
      { 
       DeleteDataDelegate((String)e.CommandArgument); 
       BindDataToRepeater(); 
      } 
     } 
     else if (e.CommandName == "Run") 
     { 
      String sRunning = (String)e.CommandArgument; 
      this.ViewDataModalPopupExtender.Hide(); 
     } 
    } 

    protected void DataRepeater_ItemDataBound(object source, RepeaterItemEventArgs e) 
    { 
     RepeaterItem item = e.Item; 
     if (item != null && item.DataItem != null) 
     { 
      MyDTO oQuery = (MyDTO)item.DataItem; 

      ImageButton oDeleteControl = (ImageButton) item.FindControl("DeleteData"); 
      ImageButton oRunControl = (ImageButton)item.FindControl("RunData"); 

      if (oDeleteControl != null && oRunControl !=null) 
      { 
       oRunControl.ImageUrl = "button_expand.gif"; 
       oRunControl.CommandArgument = "MyID"; 
       if (oQuery !=null) 
       { 
        //do something 
       } 
       oDeleteControl.ImageUrl = "btn_remove.gif"; 
       oDeleteControl.CommandArgument = "MyID"; 
      } 
     } 
    } 

    public void BindDataToRepeater() 
    { 
     this.DataRepeater.DataSource = this.PopulateDataDelegate(); 
     this.DataRepeater.DataBind(); 
    } 

    public void ShowModal(object sender, EventArgs e) 
    { 
     BindDataToRepeater(); 
     this.ViewDataModalPopupExtender.Show(); 
    } 
+0

Не хватает кода в обработчике 'ItemDataBound'? Внутри этого метода вы объявляете переменную 'MyDTO' (' oQuery'), а затем никогда не используете ее. –

+0

извините, да, я урезал его для краткости –

ответ

7

Спасибо, что напомнили мне, почему я остановил использование элементов управления ASP.NET. Это точный тип кошмара, который заставил слишком много проектов идти по бюджету и графику.

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

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

Попробуйте заменить ретранслятор простой петлей (и игнорируйте людей, которые начинают жаловаться, вы не должны смешивать разметку и код). Замените операторы привязки данных <%= %>. Это исключает состояние представления вместе и должно удалить любую удаленную строку из повторного появления.

+0

, вы совершенно правы, я перестала беспокоиться об этом сейчас, и все это jQuery с webservices. Моя жизнь на 100% проще, и все гораздо быстрее реализовать. –

1

После многих дней возиться с этим я не нашел правильное исправление для этой проблемы, но есть работоспособная обходным ,

В файле CollapsiblePanelExtender установлено значение NOT postback автоматически, что устраняет проблему повторного появления удаленных данных при открытии расширителя. Другой вопрос, я считаю, связан.

Кажется, что ViewState для повторителя не синхронизируется с данными. e.CommandArgument не всегда корректен и, похоже, ссылается на предыдущие данные. Я попытался исправить это, сохранив ArrayList объектов MyDTO в ViewState при открытии диалога Modal и используя идентификатор, полученный из e.Item.ItemIndex, чтобы найти правильный элемент для удаления. Это не сработало правильно, ArrayList, выведенный из ViewState, не синхронизирован.

Сохранение ArrayList в сеансе делает все это работой, что заставляет меня думать, что я делаю что-то принципиально неправильное или есть тонкая ошибка в версии инструментария, который я использую (мы все еще на VS2005 так застряли со старой версией инструментария)

Извините, если это не имеет смысла, свяжитесь со мной, если вы хотите получить разъяснения на что угодно.

1

попробовать с помощью

((класс IDataItemContainer) Container) .DataItem

вместо "Container.DataItem"

Он работал для меня.

Смежные вопросы