2 // System.Web.UI.StateManagedCollection
5 // Ben Maurer (bmaurer@users.sourceforge.net)
6 // Sebastien Pouliot <sebastien@ximian.com>
7 // Marek Habersack (mhabersack@novell.com)
10 // Copyright (C) 2005-2008 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections;
33 using System.Collections.Generic;
35 namespace System.Web.UI {
37 public abstract class StateManagedCollection : IList, IStateManager
39 ArrayList items = new ArrayList ();
40 bool saveEverything = false;
42 protected virtual object CreateKnownType (int index)
47 public void SetDirty ()
49 saveEverything = true;
50 for (int i = 0; i < items.Count; i++)
51 SetDirtyObject (items[i]);
54 protected abstract void SetDirtyObject (object o);
56 protected virtual Type [] GetKnownTypes ()
62 protected virtual void OnClear ()
66 protected virtual void OnClearComplete ()
70 protected virtual void OnInsert (int index, object value)
74 protected virtual void OnInsertComplete (int index, object value)
78 protected virtual void OnRemove (int index, object value)
82 protected virtual void OnRemoveComplete (int index, object value)
86 protected virtual void OnValidate (object value)
89 throw new ArgumentNullException ("value");
94 void IStateManager.LoadViewState (object savedState)
96 if (savedState == null) {
97 foreach (IStateManager i in items)
98 i.LoadViewState (null);
102 Triplet state = savedState as Triplet;
104 throw new InvalidOperationException ("Internal error.");
106 List <int> indices = state.First as List <int>;
107 List <object> states = state.Second as List <object>;
108 List <object> types = state.Third as List <object>;
109 IList list = this as IList;
113 saveEverything = indices == null;
114 if (saveEverything) {
117 for (int i = 0; i < states.Count; i++) {
120 item = (IStateManager) Activator.CreateInstance ((Type) t);
122 item = (IStateManager) CreateKnownType ((int) t);
126 item.TrackViewState ();
127 item.LoadViewState (states [i]);
134 for (int i = 0; i < indices.Count; i++) {
138 item = list [idx] as IStateManager;
139 item.TrackViewState ();
140 item.LoadViewState (states [i]);
147 item = (IStateManager) Activator.CreateInstance ((Type) t);
149 item = (IStateManager) CreateKnownType ((int) t);
153 item.TrackViewState ();
154 item.LoadViewState (states [i]);
159 void AddListItem <T> (ref List <T> list, T item)
162 list = new List <T> ();
167 object IStateManager.SaveViewState ()
169 Type[] knownTypes = GetKnownTypes ();
170 bool haveData = false, haveKnownTypes = knownTypes != null && knownTypes.Length > 0;
171 int count = items.Count;
176 List <int> indices = null;
177 List <object> states = null;
178 List <object> types = null;
180 for (int i = 0; i < count; i++) {
181 item = items [i] as IStateManager;
184 item.TrackViewState ();
185 itemState = item.SaveViewState ();
186 if (saveEverything || itemState != null) {
188 type = item.GetType ();
189 idx = haveKnownTypes ? Array.IndexOf (knownTypes, type) : -1;
192 AddListItem <int> (ref indices, i);
193 AddListItem <object> (ref states, itemState);
195 AddListItem <object> (ref types, type);
197 AddListItem <object> (ref types, idx);
204 return new Triplet (indices, states, types);
207 void IStateManager.TrackViewState ()
209 isTrackingViewState = true;
210 if (items != null && items.Count > 0) {
212 foreach (object o in items) {
213 item = o as IStateManager;
216 item.TrackViewState ();
221 bool isTrackingViewState;
222 bool IStateManager.IsTrackingViewState {
223 get { return isTrackingViewState; }
227 #region ICollection, IList, IEnumerable
233 this.OnClearComplete ();
235 if (isTrackingViewState)
239 public IEnumerator GetEnumerator ()
241 return items.GetEnumerator ();
244 public void CopyTo (Array array, int index)
246 items.CopyTo (array, index);
249 IEnumerator IEnumerable.GetEnumerator ()
251 return GetEnumerator ();
254 int IList.Add (object value)
257 if (isTrackingViewState) {
258 ((IStateManager) value).TrackViewState ();
259 SetDirtyObject (value);
262 OnInsert (-1, value);
264 OnInsertComplete (-1, value);
269 void IList.Insert (int index, object value)
272 if (isTrackingViewState) {
273 ((IStateManager) value).TrackViewState ();
277 OnInsert (index, value);
278 items.Insert (index, value);
279 OnInsertComplete(index, value);
282 void IList.Remove (object value)
287 IList list = (IList)this;
288 int i = list.IndexOf (value);
293 void IList.RemoveAt (int index)
295 object o = items [index];
298 items.RemoveAt (index);
299 OnRemoveComplete(index, o);
301 if (isTrackingViewState)
310 bool IList.Contains (object value)
316 return items.Contains (value);
319 int IList.IndexOf (object value)
325 return items.IndexOf (value);
329 get { return items.Count; }
332 int ICollection.Count {
333 get { return items.Count; }
336 bool ICollection.IsSynchronized {
337 get { return false; }
340 object ICollection.SyncRoot {
344 bool IList.IsFixedSize {
345 get { return false; }
348 bool IList.IsReadOnly {
349 get { return false; }
352 object IList.this [int index] {
353 get { return items [index]; }
355 if (index < 0 || index >= Count)
356 throw new ArgumentOutOfRangeException ("index");
359 if (isTrackingViewState) {
360 ((IStateManager) value).TrackViewState ();
364 items [index] = value;