动态向控件列表添加控件

8

我有一个网页,用户需要输入客户联系信息。他们可以输入从0到无限数量的联系人。

我在页面上创建了这个代码:

<ajaxToolkit:ToolkitScriptManager runat="Server" EnablePartialRendering="true" ID="ScriptManager1" />
<asp:PlaceHolder ID="phCustomerContacts" runat="server" EnableViewState="true">/asp:PlaceHolder>
<asp:LinkButton ID="btnAddContact" runat="server" OnClick="btnAddContact_Click" CssClass="LinkButton" Text="Add Contact"/>

在我的代码后台中,我添加了这个:

   public void btnAddContact_Click(object sender, EventArgs e)
    {
        IList<CustomerContactProfile> customerContacts = new List<CustomerContactProfile>();
        if (ViewState["CustomerContactList"] != null)
            customerContacts = (List<CustomerContactProfile>)ViewState["CustomerContactList"];
        CustomerContactProfile contactProfile = (CustomerContactProfile)LoadControl("~/Controls/Embedded/CustomerContactProfile.ascx");
        customerContacts.Add(contactProfile);

        foreach (CustomerContactProfile contact in customerContacts)
            phCustomerContacts.Controls.Add(contact);

        ViewState["CustomerContactList"] = customerContacts;
    }

这段代码无法工作,因为ViewState无法处理所有控件数据的存储。然而,我想不到其他存储已添加控件的方法。 asp:PlaceHolder控件的视图状态不保存任何内容,我需要保存控件,以便如果用户在第一个控件中输入一些数据,当他们添加第二个控件时,数据不会丢失。

1
有特别的原因必须使用Viewstate吗?你可以尝试使用Session。 - asawyer
会话可能是可以的,但如果用户离开页面,会话会不会被填满呢? - Ben Hoffman
1
会话绝对不是基于页面状态的地方。首先,这意味着,除非您采取额外措施,否则用户无法在两个单独的窗口中查看这两个页面 - 这在大多数Web应用程序中应该是可能的。 - Keith Bluestone
用户输入这些联系人后,您会对它们进行什么操作?它们会被存储在某个地方,以便当用户打开客户页面时,它们仍然存在(我想这是情况)? - Keith Bluestone
@Keith - 是的,它们将使用Entity Framework放入数据库中。 - Ben Hoffman
6个回答

1
不要存储整个控件,只需将底层数据存储在会话中,并每次重新加载页面时从该数据重建控件集。

你会如何处理控件中的数据被更改?例如,控件有一个文本框 - 如果文本框的值被更改并且页面重新加载,则更改后的值将被替换为会话中的底层数据。 - LoveFortyDown

0

我认为你不应该依赖任何临时存储 -- Viewstate、Session 或其他。

你似乎正在使用 .ascx 文件,就像我通常使用类一样... 不过,用户控件会更大,因为它有很多 HTML 内容吧?

无论如何,一个类的通用列表至少会更小。

但是,我的最爱方法是在完成每个记录时将其插入到数据库中(逐个)-- 至少对于手动输入来说,这是我对你正在处理的工作的印象。例如,使用 listview、detailsview、gridview 等。


0

我不确定动态添加联系人是否是最好的方法。使用jQuery创建控件并将数据发送到Web方法进行创建是否更好呢?


jQuery 可能更好。我只是从未使用过它。 - Ben Hoffman

0

建议在视图状态中存储要添加的控件数量,然后在页面初始化或预初始化时添加它们... 这样 ViewState 就会针对每个动态控件保留。当然,这是针对按钮点击后的 postback 操作。

希望这对您有所帮助。


@Brain - 那样做是可行的,但我会失去表单中的所有信息。 - Ben Hoffman
没有视图状态保留更改的信息,只要在 init 或 preinit 中添加控件即可。 - Brian Mains

0

将用户输入的控件数量存储在视图状态中。重写LoadViewState页面方法并在其中添加控件数量。框架会负责重新加载已发布的数据到控件中。您不会丢失信息。您只需要确保在还原视图状态之前添加控件即可。


0

将其存储在会话中,而不是视图状态。虽然效果一样糟糕,但它可以工作!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接