如何动态加载web control在postback后记住视图状态(viewstate)

在我们设计asp.net的web程序时,有时表单上的web contorl不是在设计就有的。而是在运行时才加入的。可是这就带来了一个问题,就是web contorl因为在SaveViewState之后加入,所以并没有保存,在poskback后所有已写的数据,将丢失.如何来解决上面的问题呢。我写了一个算是个web contorl的容器控件,它的由Panel继承而来的。

主要是重写表单的SaveViewState和LoadViewState:

using System.Web.UI.Design;
using System.Web.UI.Design.WebControls;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Xml;

namespace DBauer.Web.UI.WebControls
{
 [Designer("System.Web.UI.Design.ControlDesigner"), 
 ToolboxData("<{0}:DynamicControlsPanel runat=server></{0}:DynamicControlsPanel>")]

 public class DynamicControlsPanel : Panel
 {
  #region 自定义的属性

  
  [DefaultValue(HandleDynamicControls.DontPersist)]
  public HandleDynamicControls ControlsWithoutIDs
  {
   get
   {
    if(ViewState["ControlsWithoutIDs"] == null)
     return HandleDynamicControls.DontPersist;
    else
     return (HandleDynamicControls) ViewState["ControlsWithoutIDs"];
   }
   set { ViewState["ControlsWithoutIDs"] = value; }
  }

  #endregion 自定义的属性

  #region 视图状态管理
  
  protected override void LoadViewState(object savedState)
  {
   object[] viewState = (object[]) savedState;

   Pair persistInfo = (Pair) viewState[0];
   foreach(Pair pair in (ArrayList) persistInfo.Second)
   {
    RestoreChildStructure(pair, this);
   }

   base.LoadViewState(viewState[1]);
  }

  protected override object SaveViewState()
  {
   if(HttpContext.Current == null)
    return null;

   object[] viewState = new object[2];
   viewState[0] = PersistChildStructure(this, "C");
   viewState[1] = base.SaveViewState();
   return viewState;
  }

  private void RestoreChildStructure(Pair persistInfo, Control parent)
  {
   Control control;

   string[] persistedString = persistInfo.First.ToString().Split(';');

   string[] typeName = persistedString[1].Split(':');
   switch(typeName[0])
   {
 
    case "C":
     Type type = Type.GetType(typeName[1], true, true);
     try
     {
      control = (Control) Activator.CreateInstance(type);
     }
     catch(Exception e)
     {
      throw new ArgumentException(String.Format("类型 '{0}' 不能恢复状态", type.

ToString()), e);
     }
     break;
    default:
     throw new ArgumentException("无法识别的类型.不能恢复状态.");
   }

   control.ID = persistedString[2];

   switch(persistedString[0])
   {
    case "C":
     parent.Controls.Add(control);
     break;
   }

   foreach(Pair pair in (ArrayList) persistInfo.Second)
   {
    RestoreChildStructure(pair, control);
   }
  }

  private Pair PersistChildStructure(Control control, string controlCollectionName)
  {
   string typeName;
   ArrayList childPersistInfo = new ArrayList();

   if(control.ID == null)
   {
    if(ControlsWithoutIDs == HandleDynamicControls.ThrowException)
     throw new NotSupportedException("你必须设置你的ID");
    else if (ControlsWithoutIDs == HandleDynamicControls.DontPersist)
     return null;
   }

   typeName = "C:" + control.GetType().AssemblyQualifiedName;

   string persistedString = controlCollectionName + ";" + typeName + ";" + control.ID;

   if(!(control is UserControl) && !(control is CheckBoxList))
   {
    for(int counter = 0; counter < control.Controls.Count; counter++)
    {
     Control child = control.Controls[counter];
     Pair pair = PersistChildStructure(child, "C");
     if(pair != null)
      childPersistInfo.Add(pair);
    }
   }

   return new Pair(persistedString, childPersistInfo);
  }
  #endregion 视图状态管理

  #region 重化控件样式
  protected override void Render(System.Web.UI.HtmlTextWriter writer)
  {
   base.Render(writer);
  }
  //  
  #endregion 重化控件样式
 }

 public enum HandleDynamicControls
 {
  DontPersist,
  Persist,
  ThrowException
 }
}

 

希望能给有这方面问题的朋友一点帮肋.同时也欢迎大家改写的更好

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值