一个简单的例子:
public class CalcComposite:Control
{
    TextBox _operand1;
    protected override void CreateChildControls()
    {
_operand1 = new TextBox();
Controls.Add(_operand1);
    }
}
页面:
<cc1:CalcComposite id="tt" runat="server"></cc1:CalcComposite>
<asp:Button id="Button1" runat="server" Text="Button"></asp:Button>情况描述:
在CalcComposite产生的控件的子控件里输入:aaaaaa 然后点击button后,该子控件被清空了,即aaaa不见了。
如果该类实现了INamingContainer的话,点击Button之后,aaaaaa仍然存在,即子控件的值保持住了。问题:
页面Post之后,服务端应该是新建了该页面类的一个对象。该对象的Controls下有这样一个CalcComposite的对象,也是新建的。所以该CalcComposite对象的_operator1应该是在CreateChildControls的时候新建的。我跟踪过该函数,至少在该函数结束,_operand1.Text的值都还是string.Empty;是在什么时候从Post过来的表单里面取得相应的值赋给他的呢?又是通过什么东西来确定他们是相对应的呢?---------------------------------------------------
我不知道我讲明白没有。或者可以告诉我整个提交然后展示的过程。

解决方案 »

  1.   

    INamingContainer接口可以使你的控件在客户端生成html代码按照父子层次命名 当控件为复合控件时一般都要 用这个接口 只要写上就可以了 不用具体实现,它是个标记型接口
      

  2.   

    我也知道INamingContainer的作用是这个。但是,为什么不表明实现该接口,就会导致状态丢失呢?
    不信你可以试试看,如果不实现该接口,子控件的状态无法保持。我用语可以不专业,不知道你能不能听懂我的意思。
      

  3.   

    你所使用的“在CalcComposite产生的控件的子控件里输入:aaaaaa ”的文本框“TextBox   _operand1; 
            protected   override   void   CreateChildControls() 
            { 
    _operand1   =   new   TextBox(); ”
    并没有使用任何控件保存其状态,也就是说_operand1只是个临时变量,每次刷新页面当然会新建。请使用容器控件通过ViewState来保存
      

  4.   

    在page_load里面动态加个textbox
    textbox tbx = new textbox();
    if(!page.ispostback)
    {
    tbx.id = "a";
    }
    else
    {
    tbx.id = "b";
    }
    this.controls.add(tbx);
    这样你会发现在第一次提交后,该textbox 的状态也无法保存,原因同你的问的一样
      

  5.   

    不实现此接口 回发时 控件无法 按照层次结构找到html元素 写回数据。
      

  6.   


    因为你复合控件内部放了一个 TextBox,而TextBox 实现了IPostBackDataHandler接口。
    所以在内部比有IPostBackDataHandler.LoadPostData方法该方法用作“加载上一次控件属性页请求的状态,即使控件禁用视图状态,也应在回发间保存控件属性。”我们来看一下TextBox的LoadPostData的实现部分:protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
    {
        base.ValidateEvent(postDataKey
        string text = this.Text;
        string str2 = postCollection[postDataKey];
        if (!this.ReadOnly && !text.Equals(str2, StringComparison.Ordinal))
        {
            this.Text = str2;
            return true;
        }
        return false;
    }而传入的postDataKey是什么呢 这里我们就大胆猜测一下它是控件的UniqueID,
    为何这么猜测呢,http://msdn2.microsoft.com/zh-cn/library/system.web.ui.ipostbackdatahandler.loadpostdata(VS.80).aspx中参数说明指出出
    postDataKey
    控件的主要标识符。
    所以
    当不实现INamingContainer接口时控件内部的字控件无法正确的拥有UniqueID,当然无法正确LoadPostData了
    参看:引发自定义控件LoadPostData方法的必要条件