【问题标题】:ASP.NET - new user control added to control collection get unexpectedly a valueASP.NET - 添加到控件集合的新用户控件意外获得值
【发布时间】:2009-07-26 04:57:07
【问题描述】:

我创建了用户控件容器(实际上是面板),它可以动态添加和删除用户控件项(如行)。这就是问题所在:当新的用户控件被添加到控件集合时,会意外地从先前添加的控件中获得一个值 - 仅在第一次回发时。

详细说明:

  1. 在初始响应中,我填写了一个用户控件项。
  2. 然后我点击“添加”按钮,这会将新的用户控件项添加到面板中,这个新控件从前一个控件中获取值(更令人困惑的是,新控件不会获取所有值,仅形成禁用文本框控件和下拉列表)。为什么?当被添加到面板控件集合中时,UC 在服务器上获得价值。

所以我对这个问题的实现是:

            UcSomeControlItem uci = LoadControl("UcSomeControlItem .ascx") as UcSomeControlItem;
            uci.DataSource = new SomeObject;
            uci.DataBind();
            uci.ID = IdPrefix + ControlID;
            ph1.Controls.Add(uci);//At the end

当我更改添加到面板控件集合顺序的问题消失时,因为 UC 在面板添加上获得了价值...

喜欢:

            UcSomeControlItem uci = LoadControl("UcSomeControlItem .ascx") as UcSomeControlItem;
            ph1.Controls.Add(uci);//Firstly adding ..
            uci.DataSource = new SomeObject;
            uci.DataBind();
            uci.ID = IdPrefix + ControlID;

所以我想知道到底发生了什么?谁为新添加的控件设置值?

【问题讨论】:

    标签: asp.net


    【解决方案1】:

    当容器已经在页面上时,一旦您将控件添加到它的容器中,所有生命周期事件(Init、LoadViewState、Load 等)都会为新添加的控件顺序触发,直到它捕获直到父控件的生命周期当前所在的位置。

    因为您设置了控件的 ID,然后将其添加到页面中,所以当触发所有追赶事件时,它与之前的某个控件具有相同的 ID。因此,当为控件触发 LoadPostbackData 时(在加载 ViewState 后立即发生),ASP.Net 假定它与之前的控件相同,因为 ID 匹配,并继续将先前的值加载到控件中。

    当您更改它以便在将控件添加到页面之后分配 ID 时,当控件只有一个自动生成的 ID 时,所有生命周期事件都会被触发,因此回发处理器不会将其识别为以前存在的控件。

    希望这很清楚。

    【讨论】:

    • 您可以拥有完全不同的 ID,但仍会遇到此问题。对于 ViewState,默认情况下,顺序 很重要。在添加动态控件时,您必须确保保持顺序,或者,您必须在容器上设置 [ViewStateModeById] 属性(您必须定义自己的类才能这样做)。通过使用该属性,ViewState 存储(用于直接子控件)将与控件的 ID 而非控件的索引分离,并且一切都会按照您的意愿进行。
    • 没错。我实际上是在谈论 LoadPostBackData,但大多数人完全不知道其中的区别。我更新了我的答案以更清楚。
    • Michael Morton:是的,我的错误是我保留了 IDes。我不知道订单的重要性。我第一次清除面板,现在工作正常。谢谢!
    猜你喜欢
    • 2011-06-25
    • 2013-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多