为了账号安全,请及时绑定邮箱和手机立即绑定

ASP.NET动态创建的控件和回发

/ 猿问

ASP.NET动态创建的控件和回发

PIPIONE 2019-10-21 14:42:39

我知道这个问题已经被问过数千次了,之前我一直在努力,但是由于某种原因,我无法完成我想完成的工作...我有一个动态添加的LinkButton,单击该按钮可以动态添加控件(在此示例中为文本框)添加到同一面板。目的是要不断增加与单击LinkButton时一样多的控件(即,我单击一次,一个框,然后另一个单击将给我2个框,另一个单击将添加第3个框)。在下面的代码中,我使用序列化的当前日期和时间为每个文本框控件创建唯一的ID。


当我执行代码时,单击“添加筛选器”将生成一个新的文本框,但是再次单击将创建一个新的文本框,并在此之前处理该文本框。相反,我想保留先前的文本框以及其中提交的所有数据。


感谢您的帮助。


在aspx中:


<asp:Panel ID="pnlFilter" runat="server">


</asp:Panel>

在aspx.cs中:


protected void Page_Init(object sender, EventArgs e)

{

        LinkButton lb = new LinkButton();

        lb.ID = "lbAddFilter";

        pnlFilter.Controls.Add(lb);

        lb.Text = "Add Filter";

        lb.Click += new EventHandler(lbAddFilter_Click);

}



void lbAddFilter_Click(object sender, EventArgs e)

{

    TextBox tb = new TextBox();

    tb.ID = "tb" + DateTime.Now.ToBinary().ToString();

    pnlFilter.Controls.Add(tb);

}


查看完整描述

3 回答

?
拉丁的传说

对于其他试图做这样的事情的人:不要。相反,请考虑信息流并了解有一种更好的方法。无需动态创建输入控件。它们可以是静态的,并且在填写并提交后,该信息必须到达某个地方(例如,数据库,缓存,会话)。一旦到达那里,就回发,遍历您选择的存储中的所有项目并为其创建显示。

那就是我所做的,它使生活变得更加轻松。希望它可以帮助某人。


查看完整回答
反对 回复 2019-10-21
?
互换的青春

void lbAddFilter_Click(object sender, EventArgs e)

{

    TextBox tb = new TextBox();

    tb.ID = "tb" + DateTime.Now.ToBinary().ToString();

    pnlFilter.Controls.Add(tb);

}

那是行不通的-这是您在问题中得出的生命周期问题。您可以通过多种方法来使用它,但是Honus Wagner的建议是最灵活的。


这里发生的事情是您在事件处理程序中调用Controls.Add并将控件添加到控件列表中,并且在下一个请求(无论是部分回发,完整回发还是新页面命中)时,该控件之所以消失,是因为您没有在任何地方坚持下去。


这是您的页面事件生命周期中正在发生的事情:


页面调用OnInit并添加您的LinkButton

用户单击链接按钮

页面调用OnInit以开始回发请求。重新创建LinkButton

调用事件处理程序,该处理程序动态创建您的TextBox并将其添加到控件集合中

用户再次单击LinkButton

页面调用OnInit再次添加LinkButton。pnlFilter.Controls集合目前为空,除了您在标记中静态声明的任何元素外。

调用事件处理程序,并将新的TextBox添加到控件列表中。

我不确定这是否是最佳实践,但是我已经成功使用了类似的模型(请注意,我尚未测试此代码-可能需要调整):


protected override void OnInit(EventArgs e)

{

    base.OnInit(e);


    LinkButton lb = new LinkButton();

    lb.ID = "lbAddFilter";

    pnlFilter.Controls.Add(lb);

    lb.Text = "Add Filter";

    lb.Click += new EventHandler(lbAddFilter_Click);


    // regenerate dynamically created controls

    foreach ( var control in PersistedControls )

    {

        pnlFilter.Controls.Add(GenerateControl(control));

    }

}


private IList<Control> _persistedControls;

private const string PersistedControlsSessionKey = "thispage_persistedcontrols";

private IList<Control> PersistedControls

{

    if (_persistedControls == null)

    {

        if (Session[PersistedControlsSessionKey] == null)

            Session[PersistedControlsSessionKey] = new List<Control>();

        _persistedControls = Session[PersistedControlsSessionKey] as IList<Control>;

    }

    return _persistedControls;

}    


void lbAddFilter_Click(object sender, EventArgs e)

{

    TextBox tb = new TextBox();

    tb.ID = "tb" + DateTime.Now.ToBinary().ToString();

    PersistedControls.Add(tb);

    pnlFilter.Controls.Add(tb);

}

请注意,我不确定是否要向会话存储中添加实际的Control对象-我相信控件ID存在一些问题,这些问题会导致回发错误(也许Control无法序列化?)。在我开发的解决方案中,我以与GenerateControl方法等效的方式生成了一个新的TextBox / Label / ComboBox / etc,并将自定义容器类存储在PersistedControls集合中,该集合包含需要生成的UI控件的各种属性。它在每个页面上初始化。


查看完整回答
反对 回复 2019-10-21
?
慕雪9262066

我认为您需要在每次回发中重新创建每个控件。

我知道Repeater控件存储了有关其子级的足够信息,以便在数据绑定时重新创建它们……您可以使用它来节省一些工作。


查看完整回答
反对 回复 2019-10-21

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信