using System;
using System.Web.UI;
using System.Reflection;
using System.Collections.Generic;
using System.Collections;
namespace My.Common
{
[AttributeUsage(AttributeTargets.Property)]
public class ViewStateAttribute : Attribute
{
}
public class BasePage : Page
{
protected override object SaveViewState()
{
ViewStateAutoManager mgr = new ViewStateAutoManager(this);
var v = base.SaveViewState();
return mgr.SaveViewState(v);
}
protected override void LoadViewState(object savedState)
{
ViewStateAutoManager mgr = new ViewStateAutoManager(this);
var v = mgr.LoadViewState(savedState);
base.LoadViewState(v);
}
}
public class BasePart : UserControl
{
protected override object SaveViewState()
{
ViewStateAutoManager mgr = new ViewStateAutoManager(this);
var v = base.SaveViewState();
return mgr.SaveViewState(v);
}
protected override void LoadViewState(object savedState)
{
ViewStateAutoManager mgr = new ViewStateAutoManager(this);
var v = mgr.LoadViewState(savedState);
base.LoadViewState(v);
}
}
public class ViewStateAutoManager
{
private static Dictionary<Type, List<PropertyInfo>> _cache = new Dictionary<Type, List<PropertyInfo>>();
private Control _ctl;
public ViewStateAutoManager(Control ctl)
{
this._ctl = ctl;
}
private List<PropertyInfo> GetViewStateProperties(Control ctl)
{
var targetType = ctl.GetType();
if (!_cache.ContainsKey(targetType))
{
var pros = targetType.GetProperties(
BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.Instance
);
var list = new List<PropertyInfo>();
foreach (var p in pros)
{
var attr = Attribute.GetCustomAttribute(p, typeof(ViewStateAttribute));
if (attr != null)
{
list.Add(p);
}
}
_cache[targetType] = list;
}
return _cache[targetType];
}
private ViewStateList GetViewState()
{
var data = new ViewStateList();
var pros = GetViewStateProperties(_ctl);
foreach (var p in pros)
{
var value = p.GetValue(_ctl, null);
data.Add(p.Name, value);
}
return data;
}
public object SaveViewState(object parentViewState)
{
var my = GetViewState();
return new Pair(parentViewState, my);
}
private void SetViewState(object viewState)
{
var data = viewState as ViewStateList;
var pros = GetViewStateProperties(_ctl);
foreach (var p in pros)
{
p.SetValue(_ctl, data[p.Name], null);
}
}
public object LoadViewState(object parentViewState)
{
var pair = parentViewState as Pair;
SetViewState(pair.Second);
return pair.First;
}
}
[Serializable]
public class ViewStateList : IEnumerable<ViewStateList._Item>
{
[Serializable]
public class _Item
{
public string Key;
public object Value;
public _Item Next;
}
private _Item First;
public void Add(string key, object value)
{
var newItem = new _Item { Key = key, Value = value };
if (First == null)
{
First = newItem;
}
else
{
_Item last = First;
while (last.Next != null)
{
last = last.Next;
}
last.Next = newItem;
}
}
public object this[string key]
{
get
{
foreach (var p in this)
{
if (p.Key == key)
{
return p.Value;
}
}
return string.Empty;
}
}
#region IEnumerable<_Item> Members
public IEnumerator<ViewStateList._Item> GetEnumerator()
{
for (var p = First; p != null; p = p.Next)
{
yield return p;
}
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
}