.net实现控件视图状态ViewState

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

posted on 2012-02-29 16:13  hao9993  阅读(786)  评论(1编辑  收藏  举报