在回发后动态添加的控件被替换

时间:2012-12-12 15:46:11

标签: c# asp.net

好的,我的ASP页面上有一个表格如下:

<asp:Table ID="attachedFiles" runat="server" BorderColor="LightGray" BorderWidth="1" ViewStateMode="Enabled"> 
    <asp:TableRow ID = "attachedFilesRow" runat="server">
        <asp:TableCell ID="exampleCell" runat="server" Visible="false" >
            <asp:Label runat="server" Text="" />
            <asp:ImageButton runat="server" ImageAlign="Middle" ImageUrl="~/images/kill.png" OnClick="removeAttachment" />
        </asp:TableCell>
    </asp:TableRow>
</asp:Table>

我在这里创建的示例单元格不可见,因为我只将它用作我将在后面的代码中添加的其他单元格的模板:

TableCell cell = new TableCell();
TableRow row = new TableRow(); 

cell = exampleCell;
row = attachedFilesRow;

((Label)cell.Controls[0]).Text = fileName;
cell.Visible = true;
row.Cells.Add(cell);
attachedFilesRow = row;
attachedFilesRow.DataBind();

后面代码中的代码位于ASP页面上按钮的onClick方法中。我们的想法是,如果用户想要添加附件,他们会单击“添加附件”,然后将单元格添加到现有表中。该单元应该看起来像[filenName.txt X],其中X是ImageButton,以便用户可以单击它并删除附件。

我的问题是,每次用户添加附件时,先前的TableCell将替换为新的TableCell而不是添加到TableRow。我想也许是因为我正在创建一个TableCell,然后将其设置为等于已经存在的表格单元格实例,所以我尝试了这个:

ASP:

<asp:Table ID="attachedFiles" runat="server" BorderColor="LightGray" BorderWidth="1" ViewStateMode="Enabled"> 
    <asp:TableRow ID = "attachedFilesRow" runat="server">
    </asp:TableRow>
</asp:Table>

代码背后:

TableCell cell = new TableCell();

ImageButton button = new ImageButton();
button.ImageUrl = "~/images/kill.png";
button.Attributes.Add("onclick", "removeAttachment");

Label label = new Label();
label.Text = fileName;

cell.Controls.Add(button);
cell.Controls.Add(label);

attachedFilesRow.Cells.Add(cell); 

我也尝试过添加attachmentFilesRow.DataBind();到最后并尝试了两种方法来实例化新的Row和Cell Objects,而不是直接使用ASP页面中的现有方法。这些事情似乎都不起作用。

tl; dr 每次我在buttonClick上将TableCell添加到现有表格时,它都会替换我表格中的其他单元格而不是添加到其中。

编辑:

我不一定要添加新的行......这就是我想要的:

用户添加一个附件后:[fileName.txt X]

两个之后:[fileName.txt X] [fileName2.txt X]

之后三:[fileName.txt X] [fileName2.txt X] [fileName3.txt X]

它基本上是一个在Row表上,如果有意义的话,添加列或单元格。

1 个答案:

答案 0 :(得分:1)

您不是“替换”前一个单元格。在每个帖子后面ASP.NET page life-cycle开始,您将获得该页面的新实例。这是因为网络是无状态的,虽然ASP.NET给人的印象是状态并不存在。

所以,正在发生的事情是你每次都是从头开始,你总是在你的行中创建一个单元格。您需要做的是保留已添加的所有项目的列表,然后每次都通过数据绑定或代码进行渲染。

此示例应该完全您想要的内容:

namespace WebApplication1
{
    using System;
    using System.Collections.Generic;
    using System.Web.UI.WebControls;

    public partial class _Default : System.Web.UI.Page
    {
        private const string UploadViewState = "UploadViewState";

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                // initialise list and store in ViewState
                ViewState[UploadViewState] = new List<string>();
            }
        }

        protected void btnAdd_Click(object sender, EventArgs e)
        {
            // Get the list from ViewState and add the new item
            var _filesToUpload = (List<string>)ViewState[UploadViewState];
            _filesToUpload.Add(text1.Text);

            // Now recreate the row adding cells for each file...
            foreach (string item in _filesToUpload)
            {
                TableCell cell = new TableCell();
                ImageButton button = new ImageButton();
                button.ImageUrl = "~/images/kill.png";
                button.Attributes.Add("onclick", "removeAttachment");
                Label label = new Label();
                label.Text = item;
                cell.Controls.Add(button);
                cell.Controls.Add(label);
                attachedFilesRow.Cells.Add(cell);
            }
        }
    }
}

除了我的代码示例,您还可以在List<...>文件上使用数据绑定,但我只是在您的代码中继续使用。秘诀是使用List<...>个项目并存储在ViewState中,从那时起其他一切都应该是简单的。