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;
35 namespace System.Web.UI {
37 public abstract class StateManagedCollection : IList, IStateManager {
39 ArrayList items = new ArrayList ();
40 bool saveEverything = false;
41 IStateManager[] originalItems;
43 protected virtual object CreateKnownType (int index)
48 public void SetDirty ()
50 saveEverything = true;
53 protected abstract void SetDirtyObject (object o);
55 protected virtual Type [] GetKnownTypes ()
61 protected virtual void OnClear ()
65 protected virtual void OnClearComplete ()
69 protected virtual void OnInsert (int index, object value)
73 protected virtual void OnInsertComplete (int index, object value)
77 protected virtual void OnRemove (int index, object value)
81 protected virtual void OnRemoveComplete (int index, object value)
85 protected virtual void OnValidate (object value)
88 throw new ArgumentNullException ("value");
93 void IStateManager.LoadViewState (object savedState)
95 if (savedState == null) {
96 foreach (IStateManager item in items)
97 item.LoadViewState (null);
101 object[] its = (object[]) savedState;
103 saveEverything = (bool)its [0];
108 for (int n=1; n<its.Length; n++) {
113 Triplet triplet = its [n] as Triplet;
114 if (triplet != null) {
115 oi = (int) triplet.First;
116 state = triplet.Second;
117 type = triplet.Third;
119 Pair pair = (Pair) its [n];
120 oi = (int) pair.First;
127 item = originalItems [oi];
130 item = (IStateManager) Activator.CreateInstance ((Type) type);
132 item = (IStateManager) CreateKnownType ((int) type);
135 if (saveEverything) ((IList)this).Add (item);
137 item.LoadViewState (state);
141 object IStateManager.SaveViewState ()
143 object[] state = null;
144 bool hasData = false;
145 Type[] knownTypes = GetKnownTypes ();
147 if (saveEverything) {
148 state = new object [items.Count + 1];
150 for (int n=0; n<items.Count; n++)
152 IStateManager item = (IStateManager) items [n];
153 int oi = Array.IndexOf (originalItems, item);
154 object ns = item.SaveViewState ();
155 if (ns != null) hasData = true;
158 Type t = item.GetType ();
159 int idx = knownTypes == null ? -1 : Array.IndexOf (knownTypes, t);
161 state [n + 1] = new Triplet (oi, ns, idx);
163 state [n + 1] = new Triplet (oi, ns, t);
166 state [n + 1] = new Pair (oi, ns);
169 ArrayList list = new ArrayList ();
170 for (int n=0; n<items.Count; n++) {
171 IStateManager item = (IStateManager) items [n];
172 object ns = item.SaveViewState ();
175 list.Add (new Pair (n, ns));
179 list.Insert (0, false);
180 state = list.ToArray ();
190 void IStateManager.TrackViewState ()
192 isTrackingViewState = true;
193 originalItems = new IStateManager [items.Count];
194 for (int n=0; n<items.Count; n++) {
195 originalItems [n] = (IStateManager) items [n];
196 originalItems [n].TrackViewState ();
201 bool isTrackingViewState;
202 bool IStateManager.IsTrackingViewState {
203 get { return isTrackingViewState; }
207 #region ICollection, IList, IEnumerable
213 this.OnClearComplete ();
215 if (isTrackingViewState)
216 saveEverything = true;
219 public IEnumerator GetEnumerator ()
221 return items.GetEnumerator ();
224 public void CopyTo (Array array, int index)
226 items.CopyTo (array, index);
229 IEnumerator IEnumerable.GetEnumerator ()
231 return GetEnumerator ();
234 int IList.Add (object value)
237 if (isTrackingViewState) {
238 ((IStateManager) value).TrackViewState ();
239 SetDirtyObject (value);
240 saveEverything = true;
243 OnInsert (-1, value);
245 OnInsertComplete (-1, value);
250 void IList.Insert (int index, object value)
253 if (isTrackingViewState) {
254 ((IStateManager) value).TrackViewState ();
255 SetDirtyObject (value);
256 saveEverything = true;
259 OnInsert (index, value);
260 items.Insert (index, value);
261 OnInsertComplete(index, value);
264 void IList.Remove (object value)
269 int i = items.IndexOf (value);
271 ((IList)this).RemoveAt (i);
274 void IList.RemoveAt (int index)
276 object o = items [index];
279 items.RemoveAt (index);
280 OnRemoveComplete(index, o);
282 if (isTrackingViewState)
283 saveEverything = true;
291 bool IList.Contains (object value)
297 return items.Contains (value);
300 int IList.IndexOf (object value)
306 return items.IndexOf (value);
310 get { return items.Count; }
313 int ICollection.Count {
314 get { return items.Count; }
317 bool ICollection.IsSynchronized {
318 get { return false; }
321 object ICollection.SyncRoot {
325 bool IList.IsFixedSize {
326 get { return false; }
329 bool IList.IsReadOnly {
330 get { return false; }
333 object IList.this [int index] {
334 get { return items [index]; }
336 if (index < 0 || index >= Count)
337 throw new ArgumentOutOfRangeException ("index");
340 if (isTrackingViewState) {
341 ((IStateManager) value).TrackViewState ();
342 SetDirtyObject (value);
343 saveEverything = true;
346 items [index] = value;