This should fix #76928. This fix incorporates ideas from a patch
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridViewRowCollection.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Author:
23 //      Pedro Martínez Juliá <pedromj@gmail.com>
24 //
25
26
27 #if NET_2_0
28
29 using System.ComponentModel;
30 using System.Collections;
31
32 namespace System.Windows.Forms {
33
34         public class DataGridViewRowCollection : IList, ICollection, IEnumerable {
35
36                 private ArrayList list;
37                 private DataGridView dataGridView;
38
39                 private bool raiseEvent = true;
40
41                 public DataGridViewRowCollection (DataGridView dataGridView) {
42                         if (dataGridView == null) {
43                                 throw new ArgumentException("DataGridView is null.");
44                         }
45                         this.dataGridView = dataGridView;
46                         list = new ArrayList();
47                 }
48
49                 public int Count {
50                         get { return list.Count; }
51                 }
52
53                 public bool IsFixedSize {
54                         get { return list.IsFixedSize; }
55                 }
56
57                 public bool IsReadOnly {
58                         get { return list.IsReadOnly; }
59                 }
60
61                 public bool IsSynchronized {
62                         get { return list.IsSynchronized; }
63                 }
64
65                 object IList.this [int index] {
66                         get {
67                                 Console.WriteLine("acceso");
68                                 return this[index];
69                         }
70                         set { list[index] = value as DataGridViewRow; }
71                 }
72
73                 public DataGridViewRow this [int index] {
74                         get {
75                                 // Accessing a System.Windows.Forms.DataGridViewRow with this indexer causes the row to become unshared. To keep the row shared, use the System.Windows.Forms.DataGridViewRowCollection.SharedRow method. For more information, see Best Practices for Scaling the Windows Forms DataGridView Control.
76                                 return (DataGridViewRow) list[index];
77                         }
78                 }
79
80                 public object SyncRoot {
81                         get { return list.SyncRoot; }
82                 }
83
84                 public event CollectionChangeEventHandler CollectionChange;
85
86                 public virtual int Add () {
87                         return Add(dataGridView.RowTemplate.Clone() as DataGridViewRow);
88                 }
89
90                 int IList.Add(object o) {
91                         return Add(o as DataGridViewRow);
92                 }
93
94                 public virtual int Add (DataGridViewRow dataGridViewRow) {
95                         if (dataGridView.DataSource != null) {
96                                 throw new InvalidOperationException("DataSource of DataGridView is not null.");
97                         }
98                         if (dataGridView.Columns.Count == 0) {
99                                 throw new InvalidOperationException("DataGridView has no columns.");
100                         }
101                         dataGridViewRow.SetIndex(list.Count);
102                         dataGridViewRow.SetDataGridView(dataGridView);
103                         int result = list.Add(dataGridViewRow);
104                         OnCollectionChange(new CollectionChangeEventArgs(CollectionChangeAction.Add, dataGridViewRow));
105                         if (raiseEvent) {
106                                 DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(result, 1));
107                         }
108                         return result;
109                 }
110
111                 public virtual int Add (int count) {
112                         if (count <= 0) {
113                                 throw new ArgumentOutOfRangeException("Count is less than or equeal to 0.");
114                         }
115                         if (dataGridView.DataSource != null) {
116                                 throw new InvalidOperationException("DataSource of DataGridView is not null.");
117                         }
118                         if (dataGridView.Columns.Count == 0) {
119                                 throw new InvalidOperationException("DataGridView has no columns.");
120                         }
121                         raiseEvent = false;
122                         int result = 0;
123                         for (int i = 0; i < count; i++) {
124                                 result = Add(dataGridView.RowTemplate.Clone() as DataGridViewRow);
125                         }
126                         DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(result - count + 1, count));
127                         raiseEvent = true;
128                         return result;
129                 }
130
131                 public virtual int Add (params object[] values) {
132                         if (values == null) {
133                                 throw new ArgumentNullException("values is null.");
134                         }
135                         if (dataGridView.VirtualMode) {
136                                 throw new InvalidOperationException("DataGridView is in virtual mode.");
137                         }
138                         DataGridViewRow row = new DataGridViewRow();
139                         int result = Add(row);
140                         row.SetValues(values);
141                         return result;
142                 }
143
144                 public virtual int AddCopies (int indexSource, int count) {
145                         raiseEvent = false;
146                         int lastIndex = 0;
147                         for (int i = 0; i < count; i++) {
148                                 lastIndex = AddCopy(indexSource);
149                         }
150                         DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(lastIndex - count + 1, count));
151                         raiseEvent = true;
152                         return lastIndex;
153                 }
154
155                 public virtual int AddCopy (int indexSource) {
156                         return Add((list[indexSource] as DataGridViewRow).Clone() as DataGridViewRow);
157                 }
158
159                 public virtual void AddRange (params DataGridViewRow[] dataGridViewRows) {
160                         raiseEvent = false;
161                         int count = 0;
162                         int lastIndex = -1;
163                         foreach (DataGridViewRow row in dataGridViewRows) {
164                                 lastIndex = Add(row);
165                                 count++;
166                         }
167                         DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(lastIndex - count + 1, count));
168                         raiseEvent = true;
169                 }
170
171                 public virtual void Clear () {
172                         list.Clear();
173                 }
174
175                 bool IList.Contains (object o) {
176                         return Contains(o as DataGridViewRow);
177                 }
178
179                 public virtual bool Contains (DataGridViewRow dataGridViewRow) {
180                         return list.Contains(dataGridViewRow);
181                 }
182
183                 public void CopyTo (Array array, int index) {
184                         list.CopyTo(array, index);
185                 }
186
187                 public void CopyTo (DataGridViewRow[] array, int index) {
188                         list.CopyTo(array, index);
189                 }
190
191                 public IEnumerator GetEnumerator () {
192                         return list.GetEnumerator();
193                 }
194
195                 public int GetFirstRow (DataGridViewElementStates includeFilter) {
196                         for (int i = 0; i < list.Count; i++) {
197                                 DataGridViewRow row = (DataGridViewRow) list[i];
198                                 if ((row.State & includeFilter) != 0) {
199                                         return i;
200                                 }
201                         }
202                         return -1;
203                 }
204
205                 public int GetFirstRow (DataGridViewElementStates includeFilter, DataGridViewElementStates excludeFilter) {
206                         for (int i = 0; i < list.Count; i++) {
207                                 DataGridViewRow row = (DataGridViewRow) list[i];
208                                 if (((row.State & includeFilter) != 0) && ((row.State & excludeFilter) == 0)) {
209                                         return i;
210                                 }
211                         }
212                         return -1;
213                 }
214
215                 public int GetLastRow (DataGridViewElementStates includeFilter) {
216                         for (int i = list.Count - 1; i >= 0; i--) {
217                                 DataGridViewRow row = (DataGridViewRow) list[i];
218                                 if ((row.State & includeFilter) != 0) {
219                                         return i;
220                                 }
221                         }
222                         return -1;
223                 }
224
225                 public int GetNextRow (int indexStart, DataGridViewElementStates includeFilter) {
226                         for (int i = indexStart + 1; i < list.Count; i++) {
227                                 DataGridViewRow row = (DataGridViewRow) list[i];
228                                 if ((row.State & includeFilter) != 0) {
229                                         return i;
230                                 }
231                         }
232                         return -1;
233                 }
234
235                 public int GetNextRow (int indexStart, DataGridViewElementStates includeFilter, DataGridViewElementStates excludeFilter) {
236                         for (int i = indexStart + 1; i < list.Count; i++) {
237                                 DataGridViewRow row = (DataGridViewRow) list[i];
238                                 if (((row.State & includeFilter) != 0) && ((row.State & excludeFilter) == 0)) {
239                                         return i;
240                                 }
241                         }
242                         return -1;
243                 }
244
245                 public int GetPreviousRow (int indexStart, DataGridViewElementStates includeFilter) {
246                         for (int i = indexStart - 1; i >= 0; i--) {
247                                 DataGridViewRow row = (DataGridViewRow) list[i];
248                                 if ((row.State & includeFilter) != 0) {
249                                         return i;
250                                 }
251                         }
252                         return -1;
253                 }
254
255                 public int GetPreviousRow (int indexStart, DataGridViewElementStates includeFilter, DataGridViewElementStates excludeFilter) {
256                         for (int i = indexStart - 1; i >= 0; i--) {
257                                 DataGridViewRow row = (DataGridViewRow) list[i];
258                                 if (((row.State & includeFilter) != 0) && ((row.State & excludeFilter) == 0)) {
259                                         return i;
260                                 }
261                         }
262                         return -1;
263                 }
264
265                 public int GetRowCount (DataGridViewElementStates includeFilter) {
266                         int result = 0;
267                         foreach (DataGridViewRow row in list) {
268                                 if ((row.State & includeFilter) != 0) {
269                                         result ++;
270                                 }
271                         }
272                         return result;
273                 }
274
275                 public int GetRowsHeight (DataGridViewElementStates includeFilter) {
276                         int result = 0;
277                         foreach (DataGridViewRow row in list) {
278                                 if ((row.State & includeFilter) != 0) {
279                                         result += row.Height;
280                                 }
281                         }
282                         return result;
283                 }
284
285                 public virtual DataGridViewElementStates GetRowState (int rowIndex) {
286                         return (list[rowIndex] as DataGridViewRow).State;
287                 }
288
289                 int IList.IndexOf (object o) {
290                         return IndexOf(o as DataGridViewRow);
291                 }
292
293                 public int IndexOf (DataGridViewRow dataGridViewRow) {
294                         return list.IndexOf(dataGridViewRow);
295                 }
296
297                 void IList.Insert (int rowIndex, object o) {
298                         Insert(rowIndex, o as DataGridViewRow);
299                 }
300
301                 public virtual void Insert (int rowIndex, DataGridViewRow dataGridViewRow) {
302                         dataGridViewRow.SetIndex(rowIndex);
303                         dataGridViewRow.SetDataGridView(dataGridView);
304                         list[rowIndex] = dataGridViewRow;
305                         OnCollectionChange(new CollectionChangeEventArgs(CollectionChangeAction.Add, dataGridViewRow));
306                         if (raiseEvent) {
307                                 DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(rowIndex, 1));
308                         }
309                 }
310
311                 public virtual void Insert (int rowIndex, int count) {
312                         int index = rowIndex;
313                         raiseEvent = false;
314                         for (int i = 0; i < count; i++) {
315                                 Insert(index++, dataGridView.RowTemplate.Clone());
316                         }
317                         DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(rowIndex, count));
318                         raiseEvent = true;
319                 }
320
321                 public virtual void Insert (int rowIndex, params object[] values) {
322                         if (values == null) {
323                                 throw new ArgumentNullException("Values is null.");
324                         }
325                         if (dataGridView.VirtualMode || dataGridView.DataSource != null) {
326                                 throw new InvalidOperationException();
327                         }
328                         DataGridViewRow row = new DataGridViewRow();
329                         row.SetValues(values);
330                         Insert(rowIndex, row);
331                 }
332
333                 public virtual void InsertCopies (int indexSource, int indexDestination, int count) {
334                         raiseEvent = false;
335                         int index = indexDestination;
336                         for (int i = 0; i < count; i++) {
337                                 InsertCopy(indexSource, index++);
338                         }
339                         DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(indexDestination, count));
340                         raiseEvent = true;
341                 }
342
343                 public virtual void InsertCopy (int indexSource, int indexDestination) {
344                         Insert(indexDestination, (list[indexSource] as DataGridViewRow).Clone());
345                 }
346
347                 public virtual void InsertRange (int rowIndex, params DataGridViewRow[] dataGridViewRows) {
348                         raiseEvent = false;
349                         int index = rowIndex;
350                         int count = 0;
351                         foreach (DataGridViewRow row in dataGridViewRows) {
352                                 Insert(index++, row);
353                                 count++;
354                         }
355                         DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(rowIndex, count));
356                         raiseEvent = true;
357                 }
358
359                 void IList.Remove (object o) {
360                         Remove(o as DataGridViewRow);
361                 }
362
363                 public virtual void Remove (DataGridViewRow dataGridViewRow) {
364                         list.Remove(dataGridViewRow);
365                         OnCollectionChange(new CollectionChangeEventArgs(CollectionChangeAction.Remove, dataGridViewRow));
366                         DataGridView.OnRowsRemoved(new DataGridViewRowsRemovedEventArgs(dataGridViewRow.Index, 1));
367                 }
368
369                 public virtual void RemoveAt (int index) {
370                         DataGridViewRow row = this[index];
371                         list.RemoveAt(index);
372                         OnCollectionChange(new CollectionChangeEventArgs(CollectionChangeAction.Remove, row));
373                         DataGridView.OnRowsRemoved(new DataGridViewRowsRemovedEventArgs(index, 1));
374                 }
375
376                 public DataGridViewRow SharedRow (int rowIndex) {
377                         return (DataGridViewRow) list[rowIndex];
378                 }
379
380                 protected DataGridView DataGridView {
381                         get { return dataGridView; }
382                 }
383
384                 protected ArrayList List {
385                         get { return list; }
386                 }
387
388                 protected virtual void OnCollectionChange (CollectionChangeEventArgs e) {
389                         if (CollectionChange != null) {
390                                 CollectionChange(this, e);
391                         }
392                 }
393
394                 /************************/
395
396                 internal void InternalAdd (DataGridViewRow dataGridViewRow) {
397                         dataGridViewRow.SetIndex(list.Count);
398                         dataGridViewRow.SetDataGridView(dataGridView);
399                         int result = list.Add(dataGridViewRow);
400                 }
401
402                 internal ArrayList RowIndexSortedArrayList {
403                         get {
404                                 ArrayList result = (ArrayList) list.Clone();
405                                 result.Sort(new RowIndexComparator());
406                                 return result;
407                         }
408                 }
409
410                 private class RowIndexComparator : IComparer {
411
412                         public int Compare (object o1, object o2) {
413                                 DataGridViewRow row1 = (DataGridViewRow) o1;
414                                 DataGridViewRow row2 = (DataGridViewRow) o2;
415                                 if (row1.Index < row2.Index) {
416                                         return -1;
417                                 }
418                                 else if (row1.Index > row2.Index) {
419                                         return 1;
420                                 }
421                                 else {
422                                         return 0;
423                                 }
424                         }
425
426                 }
427
428                 /************************/
429
430         }
431
432 }
433
434 #endif