我的页面由上下两部分组成,上面是一个DataGrid,显示一些数据库的查询结果,下面可能有多种情况,比如一些查询的统计信息、对应的详细的属性信息、还有其它的一些东东,下面的显示根据上面所选择的记录动态改变
刚开始我是这样写的:
Page_Load 
if 显示属性 then
   Panel2.Controls.Add(LoadControl("Prop.ascx"))
elseif 显示统计信息 then
   Panel2.Controls.Add(LoadControl("Stat.ascx"))
else 其它 then
   Panel2.Controls.Add(LoadControl("Other.ascx"))
end if
结果出现了第一个错误
未能加载视图状态。正在向其中加载视图状态的控件树必须与前一请求期间用于保存视图状态的控件树相匹配。例如,当以动态方式添加控件时,在回发期间添加的控件必须与在初始请求期间添加的控件的类型和位置相匹配。后来我在每个Panel2.Controls.Add前面加上了
if request.form("__EVENTTARGET")="ShowProp" or request.form("__EVENTTARGET")="ShowStat" or request.form("__EVENTTARGET")="ShowOther" then
   Panel2.controls.clear
end if
结果又出现了第二种情况,每个控件是Load成功了,可其中的状态信息并没有保存,PostBack后,都没有加载ViewState,还是回到每个控件最初的状态,不知Page的SaveViewState何时执行,我在LoadControl后加了一个SaveViewState()语句也不行,What can I do?

解决方案 »

  1.   

    always try to load the last control displayed first, then try to remove the control and add other controls
      

  2.   

    在PageLoad上做恢复控件的事情是错误的。
    如果你执意要这样做,那么不要使用PlaceHolder,
    你可以做一个简单类代替。
    该类记录子控件的类型。
    在添加控件的时候,
    如果类型和上次不同,那么应该先调用ClearChildViewState()
      

  3.   

    能说的详细些吗?为什么不能用PlaceHolder
    LoadControl不就是写在PageLoad中吗?
      

  4.   

    yes, you should call ClearChildViewState(), the following also works:string CurrentControl
    {
      get
      {
         object o = ViewState["CurrentControl"];
         if (o == null)
           return "";     return (string)ViewState["CurrentControl"];
      }
      set
      {
         ViewState["CurrentControl"] = value;
      }
    }void Page_Load(object o, EventArgs e)
    {
        string sNewControl = "";    switch (ddl.SelectedItem.Value)
        {
            case "1":
                    sNewControl = "Drop.ascx";
                break;        case "2":
                    sNewControl = "Grid.ascx";
                break;
        }    if (CurrentControl != "")
        {
            panel1.Controls.Add(LoadControl(CurrentControl));
        }    if (sNewControl != "" && sNewControl != CurrentControl)
        {
           if (panel1.Controls.Count > 0)
            panel1.Controls.RemoveAt(0);
            
            //ClearChildViewState();
            CurrentControl = sNewControl;
            panel1.Controls.Add(LoadControl(CurrentControl));
        }
    }