[amd64/tramp] hide interpreter specific trampoline behind ifdef
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / Base / Interaction / Model / ModelItemCollection.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="ModelItemCollection.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6
7 namespace System.Activities.Presentation.Model {
8
9     using System.Activities.Presentation.Internal.Properties;
10     using System.Activities.Presentation;
11
12     using System;
13     using System.Collections;
14     using System.Collections.Generic;
15     using System.Collections.Specialized;
16     using System.Globalization;
17     using System.Windows;
18
19     /// <summary>
20     /// ModelItemCollection derives from ModelItem and implements 
21     /// support for a collection of items.  
22     ///
23     /// ModelItemCollection defines a static attached property called 
24     /// Item.  This property is returned from the Properties 
25     /// enumeration of the collection, in addition to any properties 
26     /// defined on the collection.  The Item property represents all 
27     /// the items in the collection and is defined as type 
28     /// IEnumerable of ModelItem.  All items in the collection have 
29     /// their Source property set to this property.  The property\92s metadata 
30     /// marks it non browsable and non-serializable.  The Item property is a 
31     /// "pseudo" property because it is not actually set on the model.  The 
32     /// value it points to is the ModelItemCollection itself.
33     /// </summary>
34     public abstract class ModelItemCollection : ModelItem, IList<ModelItem>, IList, INotifyCollectionChanged {
35
36         /// <summary>
37         /// Creates a new ModelItemCollection.
38         /// </summary>
39         protected ModelItemCollection() { }
40
41         /// <summary>
42         /// Returns the item at the given index.  Sets the item at the 
43         /// given index to the given value.
44         /// </summary>
45         /// <param name="index">The zero-based index into the collection.</param>
46         /// <returns></returns>
47         /// <exception cref="ArgumentNullException">if value is null.</exception>
48         /// <exception cref="IndexOutOfRangeException">if index is less than 0 or greater than or equal to count.</exception>
49         public abstract ModelItem this[int index] { get; set; }
50
51         /// <summary>
52         /// Returns the count of items in the collection.
53         /// </summary>
54         public abstract int Count { get; }
55
56         /// <summary>
57         /// Returns true if the collection is a fixed size.  
58         /// The default implementation returns true if the
59         /// collection is read only.
60         /// </summary>
61         protected virtual bool IsFixedSize {
62             get { return IsReadOnly; }
63         }
64
65         /// <summary>
66         /// Returns true if the collection cannot be modified.
67         /// </summary>
68         public abstract bool IsReadOnly { get; }
69
70         /// <summary>
71         /// Protected access to ICollection.IsSynchronized.
72         /// </summary>
73         protected virtual bool IsSynchronized {
74             get { return false; }
75         }
76
77         /// <summary>
78         /// Protected access to the SyncRoot object used to synchronize
79         /// this collection.  The default value returns "this".
80         /// </summary>
81         protected virtual object SyncRoot {
82             get { return this; }
83         }
84
85         /// <summary>
86         /// This event is raised when the contents of this collection change.
87         /// </summary>
88         public abstract event NotifyCollectionChangedEventHandler CollectionChanged;
89
90         /// <summary>
91         /// Adds the item to the collection. 
92         /// </summary>
93         /// <param name="item"></param>
94         /// <exception cref="ArgumentNullException">if item is null.</exception>
95         /// <exception cref="InvalidOperationException">if the collection is read only.</exception>
96         public abstract void Add(ModelItem item);
97
98         /// <summary>
99         /// Adds the given value to the collection.  This will create an item
100         /// for the value.  It returns the newly created item.
101         /// </summary>
102         /// <param name="value"></param>
103         /// <returns>an item representing the value</returns>
104         /// <exception cref="ArgumentNullException">if value is null.</exception>
105         /// <exception cref="InvalidOperationException">if the collection is read only.</exception>
106         public abstract ModelItem Add(object value);
107
108         /// <summary>
109         /// Clears the contents of the collection.
110         /// </summary>
111         /// <exception cref="InvalidOperationException">if the collection is read only.</exception>
112         public abstract void Clear();
113
114         /// <summary>
115         /// Returns true if the collection contains the given item.
116         /// </summary>
117         /// <param name="item"></param>
118         /// <returns></returns>
119         /// <exception cref="ArgumentNullException">if item is null.</exception>
120         public abstract bool Contains(ModelItem item);
121
122         /// <summary>
123         /// Returns true if the collection contains the given value.
124         /// </summary>
125         /// <param name="value"></param>
126         /// <returns></returns>
127         /// <exception cref="ArgumentNullException">if value is null.</exception>
128         public abstract bool Contains(object value);
129
130         //
131         // Helper method that verifies that objects can be upcast to
132         // the correct type.
133         //
134         private static ModelItem ConvertType(object value) {
135             try {
136                 return (ModelItem)value;
137             }
138             catch (InvalidCastException) {
139                 throw FxTrace.Exception.AsError(new ArgumentException(
140                     string.Format(CultureInfo.CurrentCulture,
141                         Resources.Error_ArgIncorrectType,
142                         "value", typeof(ModelItem).FullName)));
143
144             }
145         }
146
147         /// <summary>
148         /// Copies the contents of the collection into the given array.
149         /// </summary>
150         /// <exception cref="ArgumentNullException">if array is null.</exception>
151         /// <exception cref="IndexOutOfRangeException">
152         /// if arrayIndex is outside the bounds of the items array or if there is 
153         /// insuffient space in the array to hold the collection.
154         /// </exception>
155         public abstract void CopyTo(ModelItem[] array, int arrayIndex);
156
157         /// <summary>
158         /// Returns an enumerator for the items in the collection.
159         /// </summary>
160         /// <returns></returns>
161         public abstract IEnumerator<ModelItem> GetEnumerator();
162
163         /// <summary>
164         /// Returns the index of the given item or -1 if the item does not exist.
165         /// </summary>
166         /// <param name="item"></param>
167         /// <returns></returns>
168         /// <exception cref="ArgumentNullException">if item is null.</exception>
169         public abstract int IndexOf(ModelItem item);
170
171         /// <summary>
172         /// Inserts the item at the given location.  To
173         /// move an item, use Move.  If index is == Count this will insert the item 
174         /// at the end.  If it is zero it will insert at the beginning.
175         /// </summary>
176         /// <param name="index"></param>
177         /// <param name="item"></param>
178         /// <exception cref="ArgumentNullException">if item is null.</exception>
179         /// <exception cref="IndexOutOfRangeException">if index is less than 0 or greater than count.</exception>
180         public abstract void Insert(int index, ModelItem item);
181
182         /// <summary>
183         /// Inserts the item at the given location.  To
184         /// move an item, use Move.  If index is == Count this will insert the item 
185         /// at the end.  If it is zero it will insert at the beginning.
186         /// </summary>
187         /// <param name="index"></param>
188         /// <param name="value"></param>
189         /// <returns>an item representing the value</returns>
190         /// <exception cref="ArgumentNullException">if value is null.</exception>
191         /// <exception cref="IndexOutOfRangeException">if index is less than 0 or greater than count.</exception>
192         public abstract ModelItem Insert(int index, object value);
193
194         /// <summary>
195         /// Moves the item at fromIndex to toIndex.  The value for toIndex is 
196         /// always where you want the item to be according to how the collection 
197         /// currently sits.  This means that if you are moving an item to a higher 
198         /// index you don\92t have to account for the fact that the indexes will 
199         /// shuffle when the item is removed from its current location.
200         /// </summary>
201         /// <param name="fromIndex">
202         /// The index of the item to move.
203         /// </param>
204         /// <param name="toIndex">
205         /// The index to move it to.
206         /// </param>
207         /// <exception cref="IndexOutOfRangeException">
208         /// if fromIndex or toIndex is less than zero or greater than or
209         /// equal to Count.
210         /// </exception>
211         public abstract void Move(int fromIndex, int toIndex);
212
213         /// <summary>
214         /// Removes the item from the collection.  This does nothing if the 
215         /// item does not exist in the collection.
216         /// </summary>
217         /// <param name="item"></param>
218         /// <exception cref="ArgumentNullException">if item is null.</exception>
219         public abstract bool Remove(ModelItem item);
220
221         /// <summary>
222         /// Removes the value from the collection.  This does nothing if the 
223         /// value does not exist in the collection.
224         /// </summary>
225         /// <param name="value"></param>
226         /// <exception cref="ArgumentNullException">if value is null.</exception>
227         public abstract bool Remove(object value);
228
229         /// <summary>
230         /// Removes the item at the given index.
231         /// </summary>
232         /// <param name="index"></param>
233         /// <exception cref="IndexOutOfRangeException">if index is less than 0 or greater than or equal to count.</exception>
234         public abstract void RemoveAt(int index);
235
236         /// <summary>
237         /// This property is returned from the Properties enumeration of 
238         /// the collection, in addition to any properties defined on the 
239         /// collection.  The Item property represents all the items in 
240         /// the collection and is defined as type IEnumerable of ModelItem.  
241         /// All items in the collection have their Source property set to 
242         /// this property.  The property\92s metadata marks it non browsable 
243         /// and non-serializable.  The Item property is a "pseudo"property 
244         /// because it is not actually set on the model.  The value it points 
245         /// to is the ModelItemCollection itself.
246         /// </summary>
247         public static readonly DependencyProperty ItemProperty = DependencyProperty.RegisterAttachedReadOnly(
248             "Item",
249             typeof(IEnumerable<ModelItem>),
250             typeof(ModelItemCollection), null).DependencyProperty;
251
252         #region IList Members
253
254         /// <summary>
255         /// IList Implementation maps back to public API.
256         /// </summary>
257         int IList.Add(object value) {
258             Add(value);
259             return Count - 1;
260         }
261
262         /// <summary>
263         /// IList Implementation maps back to public API.
264         /// </summary>
265         void IList.Clear() {
266             Clear();
267         }
268
269         /// <summary>
270         /// IList Implementation maps back to public API.
271         /// </summary>
272         bool IList.Contains(object value) {
273             return Contains(value);
274         }
275
276         /// <summary>
277         /// IList Implementation maps back to public API.
278         /// </summary>
279         int IList.IndexOf(object value) {
280             return IndexOf(ConvertType(value));
281         }
282
283         /// <summary>
284         /// IList Implementation maps back to public API.
285         /// </summary>
286         void IList.Insert(int index, object value) {
287             Insert(index, value);
288         }
289
290         /// <summary>
291         /// IList Implementation maps back to public API.
292         /// </summary>
293         bool IList.IsFixedSize {
294             get { return IsFixedSize; }
295         }
296
297         /// <summary>
298         /// IList Implementation maps back to public API.
299         /// </summary>
300         bool IList.IsReadOnly {
301             get { return IsReadOnly; }
302         }
303
304         /// <summary>
305         /// IList Implementation maps back to public API.
306         /// </summary>
307         void IList.Remove(object value) {
308             Remove(value);
309         }
310
311         /// <summary>
312         /// IList Implementation maps back to public API.
313         /// </summary>
314         void IList.RemoveAt(int index) {
315             RemoveAt(index);
316         }
317
318         /// <summary>
319         /// IList Implementation maps back to public API.
320         /// </summary>
321         object IList.this[int index] {
322             get { return this[index]; }
323             set { this[index] = ConvertType(value); }
324         }
325
326         #endregion
327
328         #region ICollection Members
329
330         /// <summary>
331         /// ICollection Implementation maps back to public API.
332         /// </summary>
333         void ICollection.CopyTo(Array array, int index) {
334             for (int idx = 0; idx < Count; idx++) {
335                 array.SetValue(this[idx], idx + index);
336             }
337         }
338
339         /// <summary>
340         /// ICollection Implementation maps back to public API.
341         /// </summary>
342         int ICollection.Count {
343             get { return Count; }
344         }
345
346         /// <summary>
347         /// ICollection Implementation maps back to public API.
348         /// </summary>
349         bool ICollection.IsSynchronized {
350             get { return IsSynchronized; }
351         }
352
353         /// <summary>
354         /// ICollection Implementation maps back to public API.
355         /// </summary>
356         object ICollection.SyncRoot {
357             get { return SyncRoot; }
358         }
359
360         #endregion
361
362         #region IEnumerable Members
363
364         /// <summary>
365         /// IEnumerable Implementation maps back to public API.
366         /// </summary>
367         IEnumerator IEnumerable.GetEnumerator() {
368             foreach (object o in this) {
369                 yield return o;
370             }
371         }
372
373         #endregion
374     }
375 }