.net 视图状态的管理是通过StateBag类来实现的,StateBag把视图存放在StateItem里,本人在了解源代码后,实现自己的视图状态管理类(功能跟.net的一样没有做改动)
以下是MyStateBag类的实现代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Web.UI;
namespace MyControl.CourseOfStudy.MyViewState
{
public sealed class MyStateBag:IStateManager
{
// Fields
private IDictionary bag;
private bool ignoreCase; //比较字符串时是否区分大小写
private bool marked;
// Methods
public MyStateBag():this(false) //注意它的作用,语法
{
}
public MyStateBag(bool ignoreCase)
{
this.marked = false;
this.ignoreCase = ignoreCase;
this.bag = this.CreateBag();
}
private IDictionary CreateBag()
{
return new HybridDictionary(this.ignoreCase);
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public MyStateItem Add(string key, object value)
{
if (string.IsNullOrEmpty(key))
{
throw new Exception("参数key为空!");
}
//如果不需要更新的数据不要加入bag中,效率会不会更高?
MyStateItem item = this.bag[key] as MyStateItem;
if (item == null)
{
if ((value != null) || this.marked) //这里marked标志不是针对某个MyStateItem的,而是所有的
{
item = new MyStateItem(value);
this.bag.Add(key, item);
}
}
else if ((value == null) && !this.marked) //只有value为null 并且 marked=false时才移走,这说明放在bag中的item包含不需要更新的数据
{
this.bag.Remove(key);
}
else
{
item.Value = value;
}
if ((item != null) && this.marked)
{
item.IsDirty = true;
}
return item;
}
internal bool IsTrackingViewState
{
get
{
return this.marked;
}
}
internal void LoadViewState(object state)
{
if (state != null)
{
ArrayList list = (ArrayList)state;
for (int i = 0; i < list.Count; i += 2)
{
string key = list[i].ToString();
object obj = list[i + 1];
this.Add(key, obj);
}
}
}
internal object SaveViewState()
{
ArrayList list = null;
if (this.bag.Count != 0)
{
IDictionaryEnumerator enumerator = this.bag.GetEnumerator();
while (enumerator.MoveNext())
{
//或MyStateItem item = (MyStateItem)enumerator.Current;
MyStateItem item = (MyStateItem)enumerator.Value;
if (item.IsDirty)
{
if (list == null)
{
list = new ArrayList();//在这里才new而不在声明时new是考虑效率,因为如果bag.Count==0就没必要new了
}
list.Add(enumerator.Key);
list.Add(item.Value);
}
}
}
return list;
}
internal void TrackViewState()
{
this.marked = true;
}
#region IStateManager 成员
bool IStateManager.IsTrackingViewState
{
get
{
return this.IsTrackingViewState;
}
}
void IStateManager.LoadViewState(object state)
{
this.LoadViewState(state);
}
object IStateManager.SaveViewState()
{
return this.SaveViewState();
}
void IStateManager.TrackViewState()
{
this.TrackViewState();
}
public object this[string key]
{
get
{
if (string.IsNullOrEmpty(key))
{
throw new Exception("参数key为空!");
}
MyStateItem item = this.bag[key] as MyStateItem;
if (item != null)
{
return item.Value; //注意MyStateItem里的Value才是视图的值!!!
}
return null;
}
set
{
this.Add(key, value); //!!!
}
}
#endregion
}
}
以下是MyStateItem类的实现代码:
namespace MyControl.CourseOfStudy.MyViewState
{
/// <summary>
/// 视图状态中所装的value,即key对应的value,因为.net框架需要判断每个value的isDirty,所以设计了MyStateItem类
/// </summary>
public sealed class MyStateItem
{
// Fields
private bool isDirty; //是否是脏数据(是否需要保存到视图状态)
private object value;
// Methods
internal MyStateItem(object initialValue)
{
this.value = initialValue;
this.isDirty = false;
}
// Properties
public bool IsDirty
{
get
{
return this.isDirty;
}
set
{
this.isDirty = value;
}
}
public object Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
}
}