在我们设计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
}
}
希望能给有这方面问题的朋友一点帮肋.同时也欢迎大家改写的更好