PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewRowCollection.cs

https://bitbucket.org/danipen/mono
C# | 594 lines | 459 code | 90 blank | 45 comment | 91 complexity | 5cb17394a4ed64fe22ee2ddb0eef6a5e MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  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. using System.ComponentModel;
  26. using System.Collections;
  27. using System.ComponentModel.Design.Serialization;
  28. namespace System.Windows.Forms
  29. {
  30. [DesignerSerializerAttribute ("System.Windows.Forms.Design.DataGridViewRowCollectionCodeDomSerializer, " + Consts.AssemblySystem_Design,
  31. "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
  32. [ListBindable (false)]
  33. public class DataGridViewRowCollection : IList, ICollection, IEnumerable
  34. {
  35. private ArrayList list;
  36. private DataGridView dataGridView;
  37. private bool raiseEvent = true;
  38. public DataGridViewRowCollection (DataGridView dataGridView)
  39. {
  40. this.dataGridView = dataGridView;
  41. list = new ArrayList ();
  42. }
  43. public int Count {
  44. get { return list.Count; }
  45. }
  46. int ICollection.Count {
  47. get { return Count; }
  48. }
  49. bool IList.IsFixedSize {
  50. get { return list.IsFixedSize; }
  51. }
  52. bool IList.IsReadOnly {
  53. get { return list.IsReadOnly; }
  54. }
  55. bool ICollection.IsSynchronized {
  56. get { return list.IsSynchronized; }
  57. }
  58. object IList.this [int index] {
  59. get {
  60. return this[index];
  61. }
  62. set { list[index] = value as DataGridViewRow; }
  63. }
  64. public DataGridViewRow this [int index] {
  65. get {
  66. // Accessing a System.Windows.Forms.DataGridViewRow with this indexer causes the row to become unshared.
  67. // To keep the row shared, use the System.Windows.Forms.DataGridViewRowCollection.SharedRow method.
  68. // For more information, see Best Practices for Scaling the Windows Forms DataGridView Control.
  69. DataGridViewRow row = (DataGridViewRow) list [index];
  70. if (row.Index == -1) {
  71. row = (DataGridViewRow) row.Clone ();
  72. row.SetIndex (index);
  73. list [index] = row;
  74. }
  75. return row;
  76. }
  77. }
  78. object ICollection.SyncRoot {
  79. get { return list.SyncRoot; }
  80. }
  81. public event CollectionChangeEventHandler CollectionChanged;
  82. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  83. public virtual int Add ()
  84. {
  85. return Add (dataGridView.RowTemplateFull as DataGridViewRow);
  86. }
  87. int IList.Add (object value)
  88. {
  89. return Add (value as DataGridViewRow);
  90. }
  91. private int AddCore (DataGridViewRow dataGridViewRow, bool sharable)
  92. {
  93. if (dataGridView.Columns.Count == 0)
  94. throw new InvalidOperationException ("DataGridView has no columns.");
  95. int result;
  96. dataGridViewRow.SetDataGridView (dataGridView);
  97. //
  98. // Add the row just before the editing row (if there is an editing row).
  99. //
  100. int editing_index = -1;
  101. if (DataGridView != null && DataGridView.EditingRow != null && DataGridView.EditingRow != dataGridViewRow) {
  102. editing_index = list.Count - 1; // always the last row
  103. DataGridView.EditingRow.SetIndex (list.Count);
  104. }
  105. if (editing_index >= 0) {
  106. list.Insert (editing_index, dataGridViewRow);
  107. result = editing_index;
  108. } else {
  109. result = list.Add (dataGridViewRow);
  110. }
  111. if (sharable && CanBeShared (dataGridViewRow)) {
  112. dataGridViewRow.SetIndex (-1);
  113. } else {
  114. dataGridViewRow.SetIndex (result);
  115. }
  116. CompleteRowCells (dataGridViewRow);
  117. for (int i = 0; i < dataGridViewRow.Cells.Count; i++) {
  118. dataGridViewRow.Cells [i].SetOwningColumn (dataGridView.Columns [i]);
  119. }
  120. if (raiseEvent) {
  121. OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Add, dataGridViewRow));
  122. DataGridView.OnRowsAddedInternal (new DataGridViewRowsAddedEventArgs (result, 1));
  123. }
  124. return result;
  125. }
  126. // Complete the rows if they are incomplete.
  127. private void CompleteRowCells (DataGridViewRow row)
  128. {
  129. if (row == null || DataGridView == null)
  130. return;
  131. if (row.Cells.Count < DataGridView.ColumnCount) {
  132. for (int i = row.Cells.Count; i < DataGridView.ColumnCount; i++)
  133. row.Cells.Add ((DataGridViewCell) DataGridView.Columns[i].CellTemplate.Clone ());
  134. }
  135. }
  136. public virtual int Add (DataGridViewRow dataGridViewRow)
  137. {
  138. if (dataGridView.DataSource != null)
  139. throw new InvalidOperationException ("DataSource of DataGridView is not null.");
  140. return AddCore (dataGridViewRow, true);
  141. }
  142. private bool CanBeShared (DataGridViewRow row)
  143. {
  144. // We don't currently support shared rows
  145. return false;
  146. //foreach (DataGridViewCell cell in row.Cells) {
  147. // if (cell.Value != null)
  148. // return false;
  149. // if (cell.ToolTipText != string.Empty)
  150. // return false;
  151. // if (cell.ContextMenuStrip != null)
  152. // return false;
  153. //}
  154. //return true;
  155. }
  156. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  157. public virtual int Add (int count)
  158. {
  159. if (count <= 0)
  160. throw new ArgumentOutOfRangeException("Count is less than or equeal to 0.");
  161. if (dataGridView.DataSource != null)
  162. throw new InvalidOperationException("DataSource of DataGridView is not null.");
  163. if (dataGridView.Columns.Count == 0)
  164. throw new InvalidOperationException("DataGridView has no columns.");
  165. raiseEvent = false;
  166. int result = 0;
  167. for (int i = 0; i < count; i++)
  168. result = Add (dataGridView.RowTemplateFull as DataGridViewRow);
  169. DataGridView.OnRowsAddedInternal (new DataGridViewRowsAddedEventArgs (result - count + 1, count));
  170. raiseEvent = true;
  171. return result;
  172. }
  173. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  174. public virtual int Add (params object[] values)
  175. {
  176. if (values == null)
  177. throw new ArgumentNullException("values is null.");
  178. if (dataGridView.VirtualMode)
  179. throw new InvalidOperationException("DataGridView is in virtual mode.");
  180. DataGridViewRow row = (DataGridViewRow)dataGridView.RowTemplateFull;
  181. int result = AddCore (row, false);
  182. row.SetValues(values);
  183. return result;
  184. }
  185. public virtual int AddCopies (int indexSource, int count)
  186. {
  187. raiseEvent = false;
  188. int lastIndex = 0;
  189. for (int i = 0; i < count; i++)
  190. lastIndex = AddCopy(indexSource);
  191. DataGridView.OnRowsAddedInternal (new DataGridViewRowsAddedEventArgs (lastIndex - count + 1, count));
  192. raiseEvent = true;
  193. return lastIndex;
  194. }
  195. public virtual int AddCopy (int indexSource)
  196. {
  197. return Add ((list [indexSource] as DataGridViewRow).Clone () as DataGridViewRow);
  198. }
  199. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  200. public virtual void AddRange (params DataGridViewRow [] dataGridViewRows)
  201. {
  202. if (dataGridView.DataSource != null)
  203. throw new InvalidOperationException ("DataSource of DataGridView is not null.");
  204. int count = 0;
  205. int lastIndex = -1;
  206. raiseEvent = false;
  207. foreach (DataGridViewRow row in dataGridViewRows) {
  208. lastIndex = Add (row);
  209. count++;
  210. }
  211. raiseEvent = true;
  212. DataGridView.OnRowsAddedInternal (new DataGridViewRowsAddedEventArgs (lastIndex - count + 1, count));
  213. OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Add, dataGridViewRows));
  214. }
  215. public virtual void Clear ()
  216. {
  217. int total = list.Count;
  218. DataGridView.OnRowsPreRemovedInternal (new DataGridViewRowsRemovedEventArgs (0, total));
  219. for (int i = 0; i < total; i++) {
  220. DataGridViewRow row = (DataGridViewRow)list[0];
  221. // We can exit because the NewRow is always last
  222. if (row.IsNewRow)
  223. break;
  224. row.SetDataGridView (null);
  225. list.Remove (row);
  226. ReIndex ();
  227. }
  228. DataGridView.OnRowsPostRemovedInternal (new DataGridViewRowsRemovedEventArgs (0, total));
  229. OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Refresh, null));
  230. }
  231. internal void ClearInternal ()
  232. {
  233. list.Clear ();
  234. }
  235. bool IList.Contains (object value)
  236. {
  237. return Contains (value as DataGridViewRow);
  238. }
  239. public virtual bool Contains (DataGridViewRow dataGridViewRow)
  240. {
  241. return list.Contains (dataGridViewRow);
  242. }
  243. void ICollection.CopyTo (Array array, int index)
  244. {
  245. list.CopyTo (array, index);
  246. }
  247. public void CopyTo (DataGridViewRow[] array, int index)
  248. {
  249. list.CopyTo (array, index);
  250. }
  251. IEnumerator IEnumerable.GetEnumerator ()
  252. {
  253. return list.GetEnumerator ();
  254. }
  255. public int GetFirstRow (DataGridViewElementStates includeFilter)
  256. {
  257. for (int i = 0; i < list.Count; i++) {
  258. DataGridViewRow row = (DataGridViewRow) list [i];
  259. if ((row.State & includeFilter) != 0)
  260. return i;
  261. }
  262. return -1;
  263. }
  264. public int GetFirstRow (DataGridViewElementStates includeFilter, DataGridViewElementStates excludeFilter)
  265. {
  266. for (int i = 0; i < list.Count; i++) {
  267. DataGridViewRow row = (DataGridViewRow) list [i];
  268. if (((row.State & includeFilter) != 0) && ((row.State & excludeFilter) == 0))
  269. return i;
  270. }
  271. return -1;
  272. }
  273. public int GetLastRow (DataGridViewElementStates includeFilter)
  274. {
  275. for (int i = list.Count - 1; i >= 0; i--) {
  276. DataGridViewRow row = (DataGridViewRow) list [i];
  277. if ((row.State & includeFilter) != 0)
  278. return i;
  279. }
  280. return -1;
  281. }
  282. public int GetNextRow (int indexStart, DataGridViewElementStates includeFilter)
  283. {
  284. for (int i = indexStart + 1; i < list.Count; i++) {
  285. DataGridViewRow row = (DataGridViewRow) list [i];
  286. if ((row.State & includeFilter) != 0)
  287. return i;
  288. }
  289. return -1;
  290. }
  291. public int GetNextRow (int indexStart, DataGridViewElementStates includeFilter, DataGridViewElementStates excludeFilter)
  292. {
  293. for (int i = indexStart + 1; i < list.Count; i++) {
  294. DataGridViewRow row = (DataGridViewRow) list [i];
  295. if (((row.State & includeFilter) != 0) && ((row.State & excludeFilter) == 0))
  296. return i;
  297. }
  298. return -1;
  299. }
  300. public int GetPreviousRow (int indexStart, DataGridViewElementStates includeFilter)
  301. {
  302. for (int i = indexStart - 1; i >= 0; i--) {
  303. DataGridViewRow row = (DataGridViewRow) list [i];
  304. if ((row.State & includeFilter) != 0)
  305. return i;
  306. }
  307. return -1;
  308. }
  309. public int GetPreviousRow (int indexStart, DataGridViewElementStates includeFilter, DataGridViewElementStates excludeFilter)
  310. {
  311. for (int i = indexStart - 1; i >= 0; i--) {
  312. DataGridViewRow row = (DataGridViewRow) list [i];
  313. if (((row.State & includeFilter) != 0) && ((row.State & excludeFilter) == 0))
  314. return i;
  315. }
  316. return -1;
  317. }
  318. public int GetRowCount (DataGridViewElementStates includeFilter)
  319. {
  320. int result = 0;
  321. foreach (DataGridViewRow row in list)
  322. if ((row.State & includeFilter) != 0)
  323. result ++;
  324. return result;
  325. }
  326. public int GetRowsHeight (DataGridViewElementStates includeFilter)
  327. {
  328. int result = 0;
  329. foreach (DataGridViewRow row in list)
  330. if ((row.State & includeFilter) != 0)
  331. result += row.Height;
  332. return result;
  333. }
  334. public virtual DataGridViewElementStates GetRowState (int rowIndex)
  335. {
  336. return (list [rowIndex] as DataGridViewRow).State;
  337. }
  338. int IList.IndexOf (object value)
  339. {
  340. return IndexOf (value as DataGridViewRow);
  341. }
  342. public int IndexOf (DataGridViewRow dataGridViewRow)
  343. {
  344. return list.IndexOf (dataGridViewRow);
  345. }
  346. void IList.Insert (int index, object value)
  347. {
  348. Insert (index, value as DataGridViewRow);
  349. }
  350. // FIXME: Do *not* allow insertation *after* the editing row!
  351. public virtual void Insert (int rowIndex, DataGridViewRow dataGridViewRow)
  352. {
  353. dataGridViewRow.SetIndex (rowIndex);
  354. dataGridViewRow.SetDataGridView (dataGridView);
  355. CompleteRowCells (dataGridViewRow);
  356. list.Insert (rowIndex, dataGridViewRow);
  357. ReIndex ();
  358. OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Add, dataGridViewRow));
  359. if (raiseEvent)
  360. DataGridView.OnRowsAddedInternal (new DataGridViewRowsAddedEventArgs (rowIndex, 1));
  361. }
  362. public virtual void Insert (int rowIndex, int count)
  363. {
  364. int index = rowIndex;
  365. raiseEvent = false;
  366. for (int i = 0; i < count; i++)
  367. Insert (index++, dataGridView.RowTemplateFull);
  368. DataGridView.OnRowsAddedInternal (new DataGridViewRowsAddedEventArgs (rowIndex, count));
  369. raiseEvent = true;
  370. }
  371. public virtual void Insert (int rowIndex, params object[] values)
  372. {
  373. if (values == null)
  374. throw new ArgumentNullException ("Values is null.");
  375. if (dataGridView.VirtualMode || dataGridView.DataSource != null)
  376. throw new InvalidOperationException ();
  377. DataGridViewRow row = dataGridView.RowTemplateFull;
  378. row.SetValues (values);
  379. Insert (rowIndex, row);
  380. }
  381. public virtual void InsertCopies (int indexSource, int indexDestination, int count)
  382. {
  383. raiseEvent = false;
  384. int index = indexDestination;
  385. for (int i = 0; i < count; i++)
  386. InsertCopy (indexSource, index++);
  387. DataGridView.OnRowsAddedInternal (new DataGridViewRowsAddedEventArgs (indexDestination, count));
  388. raiseEvent = true;
  389. }
  390. public virtual void InsertCopy (int indexSource, int indexDestination)
  391. {
  392. Insert (indexDestination, (list [indexSource] as DataGridViewRow).Clone());
  393. }
  394. public virtual void InsertRange (int rowIndex, params DataGridViewRow [] dataGridViewRows)
  395. {
  396. raiseEvent = false;
  397. int index = rowIndex;
  398. int count = 0;
  399. foreach (DataGridViewRow row in dataGridViewRows) {
  400. Insert (index++, row);
  401. count++;
  402. }
  403. DataGridView.OnRowsAddedInternal (new DataGridViewRowsAddedEventArgs (rowIndex, count));
  404. raiseEvent = true;
  405. }
  406. void IList.Remove (object value)
  407. {
  408. Remove (value as DataGridViewRow);
  409. }
  410. public virtual void Remove (DataGridViewRow dataGridViewRow)
  411. {
  412. if (dataGridViewRow.IsNewRow)
  413. throw new InvalidOperationException ("Cannot delete the new row");
  414. DataGridView.OnRowsPreRemovedInternal (new DataGridViewRowsRemovedEventArgs (dataGridViewRow.Index, 1));
  415. dataGridViewRow.SetDataGridView (null);
  416. list.Remove (dataGridViewRow);
  417. ReIndex ();
  418. OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Remove, dataGridViewRow));
  419. DataGridView.OnRowsPostRemovedInternal (new DataGridViewRowsRemovedEventArgs (dataGridViewRow.Index, 1));
  420. }
  421. internal virtual void RemoveInternal (DataGridViewRow dataGridViewRow)
  422. {
  423. DataGridView.OnRowsPreRemovedInternal (new DataGridViewRowsRemovedEventArgs (dataGridViewRow.Index, 1));
  424. dataGridViewRow.SetDataGridView (null);
  425. list.Remove (dataGridViewRow);
  426. ReIndex ();
  427. OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Remove, dataGridViewRow));
  428. DataGridView.OnRowsPostRemovedInternal (new DataGridViewRowsRemovedEventArgs (dataGridViewRow.Index, 1));
  429. }
  430. public virtual void RemoveAt (int index)
  431. {
  432. DataGridViewRow row = this [index];
  433. Remove (row);
  434. }
  435. internal void RemoveAtInternal (int index)
  436. {
  437. DataGridViewRow row = this [index];
  438. RemoveInternal (row);
  439. }
  440. public DataGridViewRow SharedRow (int rowIndex)
  441. {
  442. return (DataGridViewRow) list [rowIndex];
  443. }
  444. internal int SharedRowIndexOf (DataGridViewRow row)
  445. {
  446. return list.IndexOf (row);
  447. }
  448. protected DataGridView DataGridView {
  449. get { return dataGridView; }
  450. }
  451. protected ArrayList List {
  452. get { return list; }
  453. }
  454. protected virtual void OnCollectionChanged (CollectionChangeEventArgs e)
  455. {
  456. if (CollectionChanged != null)
  457. CollectionChanged (this, e);
  458. }
  459. internal void AddInternal (DataGridViewRow dataGridViewRow, bool sharable)
  460. {
  461. raiseEvent = false;
  462. AddCore (dataGridViewRow, sharable);
  463. raiseEvent = true;
  464. }
  465. internal ArrayList RowIndexSortedArrayList {
  466. get {
  467. ArrayList result = (ArrayList) list.Clone();
  468. result.Sort(new RowIndexComparator());
  469. return result;
  470. }
  471. }
  472. internal void ReIndex ()
  473. {
  474. for (int i = 0; i < Count; i++)
  475. (list[i] as DataGridViewRow).SetIndex (i);
  476. }
  477. internal void Sort (IComparer comparer)
  478. {
  479. // Note: you will probably want to call
  480. // invalidate after using this.
  481. if (DataGridView != null && DataGridView.EditingRow != null)
  482. list.Sort (0, Count - 1, comparer);
  483. else
  484. list.Sort (comparer);
  485. for (int i = 0; i < list.Count; i++)
  486. (list[i] as DataGridViewRow).SetIndex (i);
  487. }
  488. private class RowIndexComparator : IComparer
  489. {
  490. public int Compare (object o1, object o2)
  491. {
  492. DataGridViewRow row1 = (DataGridViewRow) o1;
  493. DataGridViewRow row2 = (DataGridViewRow) o2;
  494. if (row1.Index < row2.Index) {
  495. return -1;
  496. } else if (row1.Index > row2.Index) {
  497. return 1;
  498. } else {
  499. return 0;
  500. }
  501. }
  502. }
  503. }
  504. }