namespace System.Web.UI.WebControls { using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; internal sealed class MethodParametersDictionary : IDictionary, IStateManager { private bool _tracking; private EventHandler _parametersChangedHandler; private Dictionary _innerDictionary; /// /// Used by Parameters to raise the ParametersChanged event. /// internal void CallOnParametersChanged() { OnParametersChanged(EventArgs.Empty); } /// /// Raises the ParametersChanged event. /// private void OnParametersChanged(EventArgs e) { if (_parametersChangedHandler != null) { _parametersChangedHandler(this, e); } } /// /// Occurs when any of the Parameter Values in the dictionary change. /// public event EventHandler ParametersChanged { add { _parametersChangedHandler = (EventHandler)Delegate.Combine(_parametersChangedHandler, value); } remove { _parametersChangedHandler = (EventHandler)Delegate.Remove(_parametersChangedHandler, value); } } public int Count { get { return InnerDictionary.Count; } } private void LoadViewState(object savedState) { if (savedState != null) { Debug.Assert(savedState is Pair); Pair pair = (Pair)savedState; string[] names = (string[])pair.First; object[] states = (object[])pair.Second; for (int i = 0; i < names.Length; i++) { string key = names[i]; Debug.Assert(!InnerDictionary.ContainsKey(key), "The collection was not empty when loading the viewstate"); MethodParameterValue parameter = new MethodParameterValue(); Add(key, parameter); ((IStateManager)parameter).LoadViewState(states[i]); } } } private object SaveViewState() { bool hasState = false; int count = Count; string[] names = new string[count]; object[] states = new object[count]; int i = 0; foreach (KeyValuePair kvp in InnerDictionary) { names[i] = kvp.Key; states[i] = ((IStateManager)kvp.Value).SaveViewState(); if (states[i] != null) hasState = true; i++; } return hasState ? new Pair(names, states) : null; } private void TrackViewState() { _tracking = true; foreach (MethodParameterValue parameter in InnerDictionary.Values) { ((IStateManager)parameter).TrackViewState(); } } private Dictionary InnerDictionary { get { if (_innerDictionary == null) { _innerDictionary = new Dictionary(); } return _innerDictionary; } } #region IDictionary> Members public ICollection Keys { get { return InnerDictionary.Keys; } } public ICollection Values { get { return InnerDictionary.Values; } } public MethodParameterValue this[string key] { get { return InnerDictionary[key]; } set { InnerDictionary[key] = value; if (value != null) { value.SetOwner(this); } } } public void Add(string key, MethodParameterValue value) { InnerDictionary.Add(key, value); if (value != null) { value.SetOwner(this); if (_tracking) { ((IStateManager)value).TrackViewState(); } } } public bool ContainsKey(string key) { return InnerDictionary.ContainsKey(key); } public bool Remove(string key) { if (InnerDictionary.ContainsKey(key)) { MethodParameterValue value = InnerDictionary[key]; if (value != null) { value.SetOwner(null); } } return InnerDictionary.Remove(key); } public bool TryGetValue(string key, out MethodParameterValue value) { return InnerDictionary.TryGetValue(key, out value); } #endregion #region ICollection> Members void ICollection>.Clear() { InnerDictionary.Clear(); } bool ICollection>.IsReadOnly { get { return ((ICollection>)InnerDictionary).IsReadOnly; } } void ICollection>.Add(KeyValuePair item) { Add(item.Key, item.Value); } bool ICollection>.Contains(KeyValuePair item) { return ((ICollection>)InnerDictionary).Contains(item); } void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) { ((ICollection>)InnerDictionary).CopyTo(array, arrayIndex); } bool ICollection>.Remove(KeyValuePair item) { return ((ICollection>)InnerDictionary).Remove(item); } #endregion #region IEnumerable> Members public IEnumerator> GetEnumerator() { return InnerDictionary.GetEnumerator(); } #endregion #region IEnumerable Members IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion #region Implementation of IStateManager bool IStateManager.IsTrackingViewState { get { return _tracking; } } void IStateManager.LoadViewState(object savedState) { LoadViewState(savedState); } object IStateManager.SaveViewState() { return SaveViewState(); } void IStateManager.TrackViewState() { TrackViewState(); } #endregion } }