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:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
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.
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
23 // Pedro MartÃnez Juliá <pedromj@gmail.com>
29 using System.ComponentModel;
30 using System.Collections;
31 using System.ComponentModel.Design.Serialization;
33 namespace System.Windows.Forms {
35 [DesignerSerializerAttribute ("System.Windows.Forms.Design.DataGridViewRowCollectionCodeDomSerializer, " + Consts.AssemblySystem_Design,
36 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
37 [ListBindable (false)]
38 public class DataGridViewRowCollection : IList, ICollection, IEnumerable {
40 private ArrayList list;
41 private DataGridView dataGridView;
43 private bool raiseEvent = true;
45 public DataGridViewRowCollection (DataGridView dataGridView)
47 this.dataGridView = dataGridView;
48 list = new ArrayList ();
52 get { return list.Count; }
60 bool IList.IsFixedSize {
61 get { return list.IsFixedSize; }
64 bool IList.IsReadOnly {
65 get { return list.IsReadOnly; }
68 bool ICollection.IsSynchronized {
69 get { return list.IsSynchronized; }
72 object IList.this [int index] {
76 set { list[index] = value as DataGridViewRow; }
79 public DataGridViewRow this [int index] {
81 // Accessing a System.Windows.Forms.DataGridViewRow with this indexer causes the row to become unshared.
82 // To keep the row shared, use the System.Windows.Forms.DataGridViewRowCollection.SharedRow method.
83 // For more information, see Best Practices for Scaling the Windows Forms DataGridView Control.
84 DataGridViewRow row = (DataGridViewRow) list [index];
85 if (row.Index == -1) {
86 row = (DataGridViewRow) row.Clone ();
94 object ICollection.SyncRoot {
95 get { return list.SyncRoot; }
98 public event CollectionChangeEventHandler CollectionChanged;
100 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
101 public virtual int Add ()
103 return Add(dataGridView.RowTemplate.Clone() as DataGridViewRow);
106 int IList.Add(object o)
108 return Add(o as DataGridViewRow);
111 internal int AddInternal (DataGridViewRow dataGridViewRow, bool sharable)
113 if (dataGridView.DataSource != null) {
114 throw new InvalidOperationException ("DataSource of DataGridView is not null.");
116 if (dataGridView.Columns.Count == 0) {
117 throw new InvalidOperationException ("DataGridView has no columns.");
119 int result = list.Add (dataGridViewRow);
120 if (sharable && CanBeShared (dataGridViewRow)) {
121 dataGridViewRow.SetIndex (-1);
123 dataGridViewRow.SetIndex (list.Count - 1);
125 dataGridViewRow.SetDataGridView (dataGridView);
127 for (int i = 0; i < dataGridViewRow.Cells.Count; i++) {
128 dataGridViewRow.Cells [i].SetOwningColumn (dataGridView.Columns [i]);
131 OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Add, dataGridViewRow));
133 DataGridView.OnRowsAddedInternal (new DataGridViewRowsAddedEventArgs (result, 1));
138 public virtual int Add (DataGridViewRow dataGridViewRow)
140 return AddInternal (dataGridViewRow, true);
143 private bool CanBeShared (DataGridViewRow row)
145 foreach (DataGridViewCell cell in row.Cells) {
146 if (cell.Value != null)
149 if (cell.ToolTipText != string.Empty)
152 if (cell.ContextMenuStrip != null)
160 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
161 public virtual int Add (int count)
164 throw new ArgumentOutOfRangeException("Count is less than or equeal to 0.");
166 if (dataGridView.DataSource != null) {
167 throw new InvalidOperationException("DataSource of DataGridView is not null.");
169 if (dataGridView.Columns.Count == 0) {
170 throw new InvalidOperationException("DataGridView has no columns.");
174 for (int i = 0; i < count; i++) {
175 result = Add(dataGridView.RowTemplate.Clone() as DataGridViewRow);
177 DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(result - count + 1, count));
182 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
183 public virtual int Add (params object[] values)
185 if (values == null) {
186 throw new ArgumentNullException("values is null.");
188 if (dataGridView.VirtualMode) {
189 throw new InvalidOperationException("DataGridView is in virtual mode.");
191 DataGridViewRow row = (DataGridViewRow)dataGridView.RowTemplateFull;
193 int result = AddInternal (row, false);
194 row.SetValues(values);
198 public virtual int AddCopies (int indexSource, int count)
202 for (int i = 0; i < count; i++) {
203 lastIndex = AddCopy(indexSource);
205 DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(lastIndex - count + 1, count));
210 public virtual int AddCopy (int indexSource)
212 return Add((list[indexSource] as DataGridViewRow).Clone() as DataGridViewRow);
215 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
216 public virtual void AddRange (params DataGridViewRow[] dataGridViewRows)
221 foreach (DataGridViewRow row in dataGridViewRows) {
222 lastIndex = Add(row);
225 DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(lastIndex - count + 1, count));
229 public virtual void Clear ()
234 bool IList.Contains (object o)
236 return Contains(o as DataGridViewRow);
239 public virtual bool Contains (DataGridViewRow dataGridViewRow)
241 return list.Contains(dataGridViewRow);
244 void ICollection.CopyTo (Array array, int index)
246 list.CopyTo(array, index);
249 public void CopyTo (DataGridViewRow[] array, int index)
251 list.CopyTo(array, index);
254 IEnumerator IEnumerable.GetEnumerator ()
256 return list.GetEnumerator();
259 public int GetFirstRow (DataGridViewElementStates includeFilter)
261 for (int i = 0; i < list.Count; i++) {
262 DataGridViewRow row = (DataGridViewRow) list[i];
263 if ((row.State & includeFilter) != 0) {
270 public int GetFirstRow (DataGridViewElementStates includeFilter, DataGridViewElementStates excludeFilter)
272 for (int i = 0; i < list.Count; i++) {
273 DataGridViewRow row = (DataGridViewRow) list[i];
274 if (((row.State & includeFilter) != 0) && ((row.State & excludeFilter) == 0)) {
281 public int GetLastRow (DataGridViewElementStates includeFilter)
283 for (int i = list.Count - 1; i >= 0; i--) {
284 DataGridViewRow row = (DataGridViewRow) list[i];
285 if ((row.State & includeFilter) != 0) {
292 public int GetNextRow (int indexStart, DataGridViewElementStates includeFilter)
294 for (int i = indexStart + 1; i < list.Count; i++) {
295 DataGridViewRow row = (DataGridViewRow) list[i];
296 if ((row.State & includeFilter) != 0) {
303 public int GetNextRow (int indexStart, DataGridViewElementStates includeFilter, DataGridViewElementStates excludeFilter)
305 for (int i = indexStart + 1; i < list.Count; i++) {
306 DataGridViewRow row = (DataGridViewRow) list[i];
307 if (((row.State & includeFilter) != 0) && ((row.State & excludeFilter) == 0)) {
314 public int GetPreviousRow (int indexStart, DataGridViewElementStates includeFilter)
316 for (int i = indexStart - 1; i >= 0; i--) {
317 DataGridViewRow row = (DataGridViewRow) list[i];
318 if ((row.State & includeFilter) != 0) {
325 public int GetPreviousRow (int indexStart, DataGridViewElementStates includeFilter, DataGridViewElementStates excludeFilter)
327 for (int i = indexStart - 1; i >= 0; i--) {
328 DataGridViewRow row = (DataGridViewRow) list[i];
329 if (((row.State & includeFilter) != 0) && ((row.State & excludeFilter) == 0)) {
336 public int GetRowCount (DataGridViewElementStates includeFilter)
339 foreach (DataGridViewRow row in list) {
340 if ((row.State & includeFilter) != 0) {
347 public int GetRowsHeight (DataGridViewElementStates includeFilter)
350 foreach (DataGridViewRow row in list) {
351 if ((row.State & includeFilter) != 0) {
352 result += row.Height;
358 public virtual DataGridViewElementStates GetRowState (int rowIndex)
360 return (list[rowIndex] as DataGridViewRow).State;
363 int IList.IndexOf (object o)
365 return IndexOf(o as DataGridViewRow);
368 public int IndexOf (DataGridViewRow dataGridViewRow)
370 return list.IndexOf(dataGridViewRow);
373 void IList.Insert (int rowIndex, object o)
375 Insert(rowIndex, o as DataGridViewRow);
378 public virtual void Insert (int rowIndex, DataGridViewRow dataGridViewRow)
380 dataGridViewRow.SetIndex(rowIndex);
381 dataGridViewRow.SetDataGridView(dataGridView);
382 list[rowIndex] = dataGridViewRow;
383 OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Add, dataGridViewRow));
385 DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(rowIndex, 1));
389 public virtual void Insert (int rowIndex, int count)
391 int index = rowIndex;
393 for (int i = 0; i < count; i++) {
394 Insert(index++, dataGridView.RowTemplate.Clone());
396 DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(rowIndex, count));
400 public virtual void Insert (int rowIndex, params object[] values)
402 if (values == null) {
403 throw new ArgumentNullException("Values is null.");
405 if (dataGridView.VirtualMode || dataGridView.DataSource != null) {
406 throw new InvalidOperationException();
408 DataGridViewRow row = new DataGridViewRow();
409 row.SetValues(values);
410 Insert(rowIndex, row);
413 public virtual void InsertCopies (int indexSource, int indexDestination, int count)
416 int index = indexDestination;
417 for (int i = 0; i < count; i++) {
418 InsertCopy(indexSource, index++);
420 DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(indexDestination, count));
424 public virtual void InsertCopy (int indexSource, int indexDestination)
426 Insert(indexDestination, (list[indexSource] as DataGridViewRow).Clone());
429 public virtual void InsertRange (int rowIndex, params DataGridViewRow[] dataGridViewRows)
432 int index = rowIndex;
434 foreach (DataGridViewRow row in dataGridViewRows) {
435 Insert(index++, row);
438 DataGridView.OnRowsAdded(new DataGridViewRowsAddedEventArgs(rowIndex, count));
442 void IList.Remove (object o)
444 Remove(o as DataGridViewRow);
447 public virtual void Remove (DataGridViewRow dataGridViewRow)
449 list.Remove(dataGridViewRow);
450 OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Remove, dataGridViewRow));
451 DataGridView.OnRowsRemoved(new DataGridViewRowsRemovedEventArgs(dataGridViewRow.Index, 1));
454 public virtual void RemoveAt (int index)
456 DataGridViewRow row = this[index];
457 list.RemoveAt(index);
458 OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Remove, row));
459 DataGridView.OnRowsRemoved(new DataGridViewRowsRemovedEventArgs(index, 1));
462 public DataGridViewRow SharedRow (int rowIndex)
464 return (DataGridViewRow) list[rowIndex];
467 internal int SharedRowIndexOf (DataGridViewRow row)
469 return list.IndexOf (row);
472 protected DataGridView DataGridView {
473 get { return dataGridView; }
476 protected ArrayList List {
480 protected virtual void OnCollectionChanged (CollectionChangeEventArgs e)
482 if (CollectionChanged != null) {
483 CollectionChanged (this, e);
487 /************************/
489 internal void InternalAdd (DataGridViewRow dataGridViewRow)
491 dataGridViewRow.SetIndex(list.Count);
492 dataGridViewRow.SetDataGridView(dataGridView);
493 list.Add(dataGridViewRow);
496 internal ArrayList RowIndexSortedArrayList {
498 ArrayList result = (ArrayList) list.Clone();
499 result.Sort(new RowIndexComparator());
504 private class RowIndexComparator : IComparer {
506 public int Compare (object o1, object o2) {
507 DataGridViewRow row1 = (DataGridViewRow) o1;
508 DataGridViewRow row2 = (DataGridViewRow) o2;
509 if (row1.Index < row2.Index) {
512 else if (row1.Index > row2.Index) {
522 /************************/