代码之家  ›  专栏  ›  技术社区  ›  Gordon Thompson

更新面板、中继器、数据绑定问题

  •  5
  • Gordon Thompson  · 技术社区  · 16 年前

    在一个用户控件中,我在一个更新面板内有一个中继器(它的ID显示在modalpopupExtender内)。中继器使用mydto对象的数组列表进行数据绑定。列表中每个项目都有两个按钮。绑定后,设置imageurl和commandArgument。

    这段代码第一次运行良好,但之后commandArgument就错了。显示似乎已正确更新,但DTO没有更新,发送的commandArgument是刚刚删除的。

    有人能发现代码有什么问题吗?

    编辑:我刚在代码中添加了一个折叠面板招标。当我现在删除一个项目并展开面板时,先前被删除(并从显示中消失)的项目又回来了。似乎中继器没有在发动机罩下正确重建。

    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>
    

    代码落后

        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();
        }
    
    3 回复  |  直到 14 年前
        1
  •  7
  •   Marnix van Valen    16 年前

    感谢您提醒我为什么停止使用ASP.NET控件。这正是使太多项目超出预算和进度的恶梦类型。

    我的建议是想一个最简单的方法来实现这一点。您可以尝试向后弯曲,以使其以ASP.NET方式工作,或者采用最短的路径。 您所要做的就是生成HTML,它不应该那么困难。

    问题最可能的原因是视图状态存储在不在部分回发时更新的页面中。因此,在更新面板中的每一个更改,您都将回发页面的初始视图状态。

    尝试用一个简单的for循环替换中继器(并且忽略那些开始抱怨你不应该混合标记和代码的人)。将数据绑定语句替换为 <%= %> . 这将同时消除视图状态,并应删除任何已删除的行,使其不再出现。

        2
  •  1
  •   Gordon Thompson    16 年前

    经过几天的纠缠不清,我还没有找到一个合适的解决方法,但确实有一个可行的工作。

    折叠面板投标被设置为不自动回发,这修复了在扩展程序打开时重新出现已删除数据的问题。我认为,另一个问题是相关的。

    中继器的视图状态似乎与数据不同步。e.commandArgument并不总是正确的,似乎引用了前面的数据。我试图通过在打开模式对话框时将mydto对象的arraylist存储在viewstate中并使用从e.item.itemIndex中检索到的ID查找要删除的正确元素来修复它。这不正确,从视图状态中拉出的数组列表不同步。

    将arraylist存储在会话中可以使它完全正常工作,这使我相信我在做一些根本错误的事情,或者我使用的工具箱版本中存在一个微妙的错误(我们仍然使用的是vs2005,所以仍然使用旧版本的工具箱)

    抱歉,如果这没有意义,请联系我,如果你想澄清任何事情。

        3
  •  1
  •   Kiran    14 年前

    试用使用

    ((IDataItemContainer)容器).dataItem

    而不是“ Container.DataItem

    这对我很有用。