.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; } } }}