asp.net在回发后动态添加用户控件保存值

发布于 2024-09-28 08:31:00 字数 276 浏览 0 评论 0原文

这是我的问题。我有一个用户控件,我希望允许用户通过单击按钮添加所需数量的实例(每次单击按钮时,我想将用户控件的另一个实例添加到面板中)。第一次工作正常,但每次额外的回发都会删除所有添加的控件。我可以毫无问题地跟踪用户添加的用户控件的数量,但如何确保它们保持回发之前的相同状态?我读过一些关于人们使用 SaveViewState 和 LoadViewState 的帖子,但我找不到任何示例。

我最大的问题是确保每个用户控件的所有文本框和下拉列表在每次回发后都保持填充相同的文本/选定的值/数据

提前致谢, 本

Here's my issue. I have a usercontrol that I want to allow users to add as many instances of as necessary using a button click (each time a button is clicked, I want to add another instance of my user control to a Panel). It works fine the first time, but each additional post back removes all of the added controls. I have no problem keeping track of the number of user controls a user has added but how do I ensure they stay in the same state they were before the postback? I've read some posts about people using SaveViewState and LoadViewState but I haven't been able to find any examples.

My biggest issue is ensuring that all of the text boxes and dropdownlists from each user control stays populated with the same text/selected value/data after each post back

Thanks in advance,
Ben

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

当爱已成负担 2024-10-05 08:31:00

由于您以编程方式向页面添加控件,因此您需要在每次回发时重新创建它们。

此外,您还需要在页面的 PreInitInit 事件上重新创建以编程方式添加的控件。这是为了正确的视图状态恢复事件管理。

如果您不这样做,控制权将在回发时消失,并且它们不会处理任何事件。

编辑

虽然建议在 PreInitInit 上添加动态控件,但确实(正如达斯汀·霍奇斯所说),如果将它们添加到页面加载。我想说你应该避免它,除非你别无选择。

<块引用>

您也许可以在中加载控件
Page_Load 事件处理程序并正确维护视图状态。
这完全取决于您是否以编程方式设置动态加载控件的任何属性,如果是这样,则何时相对于
控件.添加(动态控件)
线。
对此进行彻底的讨论有点超出了本文的范围,但它可能起作用的原因是因为
Controls 属性的 Add() 方法递归地将父级的视图状态加载到其子级中,即使加载视图状态阶段已经过去。

来源 MSDN

Since you're programmatically adding controls to your page, you'll need to recreate them on EACH postback.

Also, it's necessary that you recreate programmatically added controls on PreInit or Init event of the page. This is for proper viewstate restoring event management.

If you don't do this, control will be gone on postback and they won't handle any event.

EDIT

Although is recommended to add dynamically controls on PreInit or Init it's true (as Dustin Hodges says) that it may work if you add them on page_load. I'd say you should avoid it unless you have no other option.

You may be able to get away with loading your controls in the
Page_Load event handler and maintaining the view state properly.
It all depends on whether or not you are setting any properties of the dynamically loaded controls programmatically and, if so, when you're doing it relative to the
Controls.Add(dynamicControl)
line.
A thorough discussion of this is a bit beyond the scope of this article, but the reason it may work is because the
Controls property's Add() method recursively loads the parent's view state into its children, even though the load view state stage has passed.

Source MSDN

静谧 2024-10-05 08:31:00

如果您要跟踪用户添加的控件数量,则需要重新创建用户先前添加的控件,最好是在 Page_Init 或 Page_Load 中。将类似的内容添加到该处理程序中:

for(int i=0; i<NumberOfControlsUserHasAdded; i++)
{
    //todo:  change this to the appropriate user control
    TextBox tb = new TextBox();
    tb.ID = "tb" + i.ToString();
    //todo:  add to appropriate control collection
    this.Controls.Add(tb);
}

如果您这样做,则应维护控件的状态,因为当您将 tb 控件添加到控件集合时,它会赶上事件并应自动恢复其视图状态。

您不必在会话中跟踪它们的状态,因为在大多数情况下,它将存储在视图状态中

If you are keeping track of the number of controls the user has added you need to recreate the controls the user added previously, preferably in Page_Init or Page_Load. Add something like this to that handler:

for(int i=0; i<NumberOfControlsUserHasAdded; i++)
{
    //todo:  change this to the appropriate user control
    TextBox tb = new TextBox();
    tb.ID = "tb" + i.ToString();
    //todo:  add to appropriate control collection
    this.Controls.Add(tb);
}

If you do it this way, the state of the controls should be maintained because when you add the tb control to a controls collection it plays catch up with events and should automagically restore its viewstate.

You shouldn't have to keep track of their state in session as in most cases it will be stored in the viewstate for you

自此以后,行同陌路 2024-10-05 08:31:00

当我试图在一个旧项目上实现这一目标时,我经历了一场噩梦。在中间的时间里,我发现我对 Web 开发的了解比我想象的要少得多(阅读这个网站是每天(如果不是每小时)让自己谦虚的好方法)。在那个项目中,Page.IsPostBack 对我来说完全没用,因为我已经动态实例化了控件。

话虽这么说,我能建议的最好的办法是考虑使用 Session 变量。如果您有一个类(或类的集合)来表示从页面捕获的数据,那么也许最简单的方法是将值存储在该类/集合中以提高代码可读性,然后将其写出到会议。

I had a nightmare of a time trying to pull this off on an old project. In the intermediate time, I've discovered that I know a lot less about web development than I thought (reading this website is a great way to humble yourself on a daily -- if not hourly -- basis). In that project, Page.IsPostBack was totally useless to me because I had dynamically instantiated the controls.

That being said, the best thing I can suggest is to consider using the Session variable. If you have a class (or a collection of a class) that represents the data you capture from the page, then perhaps it'd be easiest to store values in that class/collection to improve code readability, and then write it out to the Session.

我恋#小黄人 2024-10-05 08:31:00

查看 PageLoad 并在清除面板的行之前添加 if(!this.IsPostBack)

这当然只是一个猜测,但我见过很多与此相关的问题

Look at your PageLoad and add if(!this.IsPostBack) before the line where you clear the panel.

this is of course just a guess, but I have seen many questions where the problem was related to this.

轮廓§ 2024-10-05 08:31:00

我认为可能发生的情况是,当您单击添加按钮时,Page_Load 会触发,从而创建一个全新的页面。然后,按钮单击方法添加控件,页面完成渲染。当您第二次单击它时,Page_Load 将创建您的页面,并且按钮单击方法会再次创建一个控件并将其添加到页面中。不幸的是,您之前添加的那个已经不存在了。

如果将控件添加到中继器会怎样? Repeater 的视图状态可能会跟踪您添加的每个控件,以便在回发时它不会被吹走。

I think what may be happening is when you click the button to add, Page_Load fires which creates you a brand new page. Then, the button click method adds the control and the page finishes rendering. When you click it the second time, Page_Load creates your page and the button click method again creates a control and adds it to the page. Unfortunately, the one you added previously is no longer there.

What if you added the controls to a Repeater? The Repeater's view state may keep track of each control you add so that on post-back, it's not blown away.

长伴 2024-10-05 08:31:00

如果您有大量用户,这是一个丑陋的解决方案,但您可以将用户控件本身粘贴到会话中。
我使用页脚控件执行此操作,因为我不想每次页面更改时都访问数据库以重新创建页脚。

如果您有很多用户并且他们经常使用此功能,那么此解决方案可能会在服务器上产生真正的任务。至少我认为它会...

但是您可以重新填充 page_load 上包含用户控件的占位符。我可以很快举一个例子。

我所做的示例:

if (Session["footer"] == null)
{
 Session["footer"] = new Footer(LinksRules.BuildFooterLinks((int)WebSiteSections.Main));// where Footer is my control
}
footerPH.Controls.Add((Footer)Session["footer"]);

就像单例模式一样......

因此,据我所知,您可以对任何会导致回发的事物执行此操作

Session["DynamicControls"] = PlaceHolder.Controls;

在页面加载方法中,您可以:

foreach(var control in (List<Controls>)Session["DynamicControls"])
{
  yourPlaceHolder.Controls.Add(control);
}

如果会话对象为空,只需添加一个对象,就像它们从未存在过一样。

我相信这会像您想要的那样挂在控件内的数据上。

It's an ugly solution if you have a ton of users, but you could stick the usercontrols themselves into the session.
I do this with my footer control because I don't want to hit the db every time the page changes to recreate the footer.

This solutions can get really tasking on the server if you have a lot of users and they use this feature a lot. At least I think it will...

But you can just repopulate your placeholder that has the usercontrols in it on page_load. I can put up an example shortly.

Example of what I do:

if (Session["footer"] == null)
{
 Session["footer"] = new Footer(LinksRules.BuildFooterLinks((int)WebSiteSections.Main));// where Footer is my control
}
footerPH.Controls.Add((Footer)Session["footer"]);

Like a singleton pattern sort of...

So as I see it you could do this on anything that will cause a postback

Session["DynamicControls"] = PlaceHolder.Controls;

and in the page-Load method you could:

foreach(var control in (List<Controls>)Session["DynamicControls"])
{
  yourPlaceHolder.Controls.Add(control);
}

and if the session object is null just add a single one like they've never been there..

I believe this will hang on to the data inside the controls like you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文