2 // System.Web.UI.StateManagedCollection
5 // Ben Maurer (bmaurer@users.sourceforge.net)
6 // Sebastien Pouliot <sebastien@ximian.com>
9 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Collections;
34 using System.Collections.Generic;
36 namespace System.Web.UI {
38 public abstract class StateManagedCollection : IList, IStateManager {
40 ArrayList items = new ArrayList ();
41 bool saveEverything = false;
43 protected virtual object CreateKnownType (int index)
48 public void SetDirty ()
50 saveEverything = true;
51 for (int i = 0; i < items.Count; i++)
52 SetDirtyObject (items[i]);
55 protected abstract void SetDirtyObject (object o);
57 protected virtual Type [] GetKnownTypes ()
63 protected virtual void OnClear ()
67 protected virtual void OnClearComplete ()
71 protected virtual void OnInsert (int index, object value)
75 protected virtual void OnInsertComplete (int index, object value)
79 protected virtual void OnRemove (int index, object value)
83 protected virtual void OnRemoveComplete (int index, object value)
87 protected virtual void OnValidate (object value)
90 throw new ArgumentNullException ("value");
95 void IStateManager.LoadViewState (object savedState)
97 if (savedState == null) {
98 foreach (IStateManager i in items)
99 i.LoadViewState (null);
103 Triplet[] state = savedState as Triplet[];
104 saveEverything = (bool)(state [0].First);
113 for (int i = 1; i < state.Length; i++) {
118 itemState = triplet.Second;
119 type = triplet.Third;
121 item = (IStateManager) Activator.CreateInstance ((Type) type);
122 else if (type is int)
123 item = (IStateManager) CreateKnownType ((int) type);
128 ((IList)this).Add (item);
130 item.TrackViewState ();
132 item.LoadViewState (itemState);
136 object IStateManager.SaveViewState ()
138 bool hasData = false;
139 Type[] knownTypes = GetKnownTypes ();
140 bool haveKnownTypes = knownTypes != null;
141 List <Triplet> state = new List <Triplet> ();
142 int count = items.Count;
148 for (int i = 0; i < count; i++) {
149 item = items [i] as IStateManager;
152 item.TrackViewState ();
153 itemState = item.SaveViewState ();
154 if (saveEverything || itemState != null) {
156 type = item.GetType ();
157 idx = haveKnownTypes ? Array.IndexOf (knownTypes, type) : -1;
159 state.Add (new Triplet (i, itemState, type));
161 state.Add (new Triplet (i, itemState, idx));
166 state.Insert (0, new Triplet (saveEverything, null, null));
167 return state.ToArray ();
172 void IStateManager.TrackViewState ()
174 isTrackingViewState = true;
175 if (items != null && items.Count > 0) {
177 foreach (object o in items) {
178 item = o as IStateManager;
181 item.TrackViewState ();
186 bool isTrackingViewState;
187 bool IStateManager.IsTrackingViewState {
188 get { return isTrackingViewState; }
192 #region ICollection, IList, IEnumerable
198 this.OnClearComplete ();
200 if (isTrackingViewState)
204 public IEnumerator GetEnumerator ()
206 return items.GetEnumerator ();
209 public void CopyTo (Array array, int index)
211 items.CopyTo (array, index);
214 IEnumerator IEnumerable.GetEnumerator ()
216 return GetEnumerator ();
219 int IList.Add (object value)
222 if (isTrackingViewState) {
223 ((IStateManager) value).TrackViewState ();
224 SetDirtyObject (value);
228 OnInsert (-1, value);
230 OnInsertComplete (-1, value);
235 void IList.Insert (int index, object value)
238 if (isTrackingViewState) {
239 ((IStateManager) value).TrackViewState ();
240 SetDirtyObject (value);
244 OnInsert (index, value);
245 items.Insert (index, value);
246 OnInsertComplete(index, value);
249 void IList.Remove (object value)
254 int i = items.IndexOf (value);
256 ((IList)this).RemoveAt (i);
259 void IList.RemoveAt (int index)
261 object o = items [index];
264 items.RemoveAt (index);
265 OnRemoveComplete(index, o);
267 if (isTrackingViewState)
276 bool IList.Contains (object value)
282 return items.Contains (value);
285 int IList.IndexOf (object value)
291 return items.IndexOf (value);
295 get { return items.Count; }
298 int ICollection.Count {
299 get { return items.Count; }
302 bool ICollection.IsSynchronized {
303 get { return false; }
306 object ICollection.SyncRoot {
310 bool IList.IsFixedSize {
311 get { return false; }
314 bool IList.IsReadOnly {
315 get { return false; }
318 object IList.this [int index] {
319 get { return items [index]; }
321 if (index < 0 || index >= Count)
322 throw new ArgumentOutOfRangeException ("index");
325 if (isTrackingViewState) {
326 ((IStateManager) value).TrackViewState ();
327 SetDirtyObject (value);
331 items [index] = value;