2 // System.Data.DataColumnCollection.cs
5 // Christopher Podurgiel (cpodurgiel@msn.com)
11 using System.Collections;
12 using System.ComponentModel;
17 /// Represents a collection of DataColumn objects for a DataTable.
19 public class DataColumnCollection : InternalDataCollectionBase
24 // The defaultNameIndex is used to create a default name for a column if one wasn't given.
25 private int defaultNameIndex;
27 //table should be the DataTable this DataColumnCollection belongs to.
28 private DataTable parentTable = null;
30 // Internal Constructor. This Class can only be created from other classes in this assembly.
31 internal DataColumnCollection(DataTable table):base()
40 /// Gets the DataColumn from the collection at the specified index.
42 public virtual DataColumn this[int index]
46 return (DataColumn) base.List[index];
51 /// Gets the DataColumn from the collection with the specified name.
53 public virtual DataColumn this[string name]
57 foreach (DataColumn column in base.List)
59 if (column.ColumnName == name)
72 /// Gets a list of the DataColumnCollection items.
74 protected override ArrayList List
86 //DefaultValue set and AutoInc set check
87 //?Validate Expression??
88 //Name check and creation
90 //Check Unique if true then add a unique constraint
91 //?Notify Rows of new column ?
96 /// Creates and adds a DataColumn object to the DataColumnCollection.
98 /// <returns></returns>
99 public virtual DataColumn Add()
102 DataColumn column = new DataColumn("Column" + defaultNameIndex.ToString());
103 CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Add, this);
105 column.SetTable(parentTable);
106 base.List.Add(column);
107 OnCollectionChanged(e);
113 /// Creates and adds the specified DataColumn object to the DataColumnCollection.
115 /// <param name="column">The DataColumn to add.</param>
116 public void Add(DataColumn column)
119 if(Contains(column.ColumnName))
121 throw new DuplicateNameException("A column named " + column.ColumnName + " already belongs to this DataTable.");
125 CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Add, this);
127 column.SetTable( parentTable);
128 base.List.Add(column);
129 OnCollectionChanged(e);
135 /// Creates and adds a DataColumn object with the specified name to the DataColumnCollection.
137 /// <param name="columnName">The name of the column.</param>
138 /// <returns>The newly created DataColumn.</returns>
139 public virtual DataColumn Add(string columnName)
142 //FIXME: this wont work. If the user decides to add a column named
143 //"ColumnXX" where XX is a number these two will conflict.
144 if (columnName == null || columnName == String.Empty)
146 columnName = "Column" + defaultNameIndex.ToString();
150 if(Contains(columnName))
152 throw new DuplicateNameException("A column named " + columnName + " already belongs to this DataTable.");
156 DataColumn column = new DataColumn(columnName);
158 CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Add, this);
159 column.SetTable(parentTable);
160 base.List.Add(column);
161 OnCollectionChanged(e);
167 /// Creates and adds a DataColumn object with the specified name and type to the DataColumnCollection.
169 /// <param name="columnName">The ColumnName to use when cretaing the column.</param>
170 /// <param name="type">The DataType of the new column.</param>
171 /// <returns>The newly created DataColumn.</returns>
172 public virtual DataColumn Add(string columnName, Type type)
174 if (columnName == null || columnName == "")
176 //FIXME: this wont work. If the user decides to add a column named
177 //"ColumnXX" where XX is a number these two will conflict.
178 columnName = "Column" + defaultNameIndex.ToString();
182 if(Contains(columnName))
184 throw new DuplicateNameException("A column named " + columnName + " already belongs to this DataTable.");
188 DataColumn column = new DataColumn(columnName, type);
189 CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Add, this);
190 column.SetTable(parentTable);
191 base.List.Add(column);
192 OnCollectionChanged(e);
198 /// Creates and adds a DataColumn object with the specified name, type, and expression to the DataColumnCollection.
200 /// <param name="columnName">The name to use when creating the column.</param>
201 /// <param name="type">The DataType of the new column.</param>
202 /// <param name="expression">The expression to assign to the Expression property.</param>
203 /// <returns>The newly created DataColumn.</returns>
204 public virtual DataColumn Add(string columnName, Type type, string expression)
206 //FIXME: See Add Logic
207 if (columnName == null || columnName == "")
209 columnName = "Column" + defaultNameIndex.ToString();
213 if(Contains(columnName))
215 throw new DuplicateNameException("A column named " + columnName + " already belongs to this DataTable.");
219 DataColumn column = new DataColumn(columnName, type, expression);
220 CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Add, this);
221 column.SetTable(parentTable);
222 base.List.Add(column);
223 OnCollectionChanged(e);
229 /// Copies the elements of the specified DataColumn array to the end of the collection.
231 /// <param name="columns">The array of DataColumn objects to add to the collection.</param>
232 public void AddRange(DataColumn[] columns)
234 foreach (DataColumn column in columns)
242 /// Checks whether a given column can be removed from the collection.
244 /// <param name="column">A DataColumn in the collection.</param>
245 /// <returns>true if the column can be removed; otherwise, false.</returns>
246 public bool CanRemove(DataColumn column)
249 //Check that the column does not have a null reference.
256 //Check that the column is part of this collection.
257 if (!Contains(column.ColumnName))
264 //Check if this column is part of a relationship. (this could probably be written better)
265 foreach (DataRelation childRelation in parentTable.ChildRelations)
267 foreach (DataColumn childColumn in childRelation.ChildColumns)
269 if (childColumn == column)
275 foreach (DataColumn parentColumn in childRelation.ParentColumns)
277 if (parentColumn == column)
284 //Check if this column is part of a relationship. (this could probably be written better)
285 foreach (DataRelation parentRelation in parentTable.ParentRelations)
287 foreach (DataColumn childColumn in parentRelation.ChildColumns)
289 if (childColumn == column)
295 foreach (DataColumn parentColumn in parentRelation.ParentColumns)
297 if (parentColumn == column)
305 //Check if another column's expression depends on this column.
307 foreach (DataColumn dataColumn in List)
309 if (dataColumn.Expression.ToString().IndexOf(column.ColumnName) > 0)
315 //TODO: check constraints
321 /// Clears the collection of any columns.
325 CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Refresh, this);
327 OnCollectionChanged(e);
332 /// Checks whether the collection contains a column with the specified name.
334 /// <param name="name">The ColumnName of the column to check for.</param>
335 /// <returns>true if a column exists with this name; otherwise, false.</returns>
336 public bool Contains(string name)
338 return (IndexOf(name) != -1);
342 /// Gets the index of a column specified by name.
344 /// <param name="column">The name of the column to return.</param>
345 /// <returns>The index of the column specified by column if it is found; otherwise, -1.</returns>
346 public virtual int IndexOf(DataColumn column)
348 return base.List.IndexOf(column);
352 /// Gets the index of the column with the given name (the name is not case sensitive).
354 /// <param name="columnName">The name of the column to find.</param>
355 /// <returns>The zero-based index of the column with the specified name, or -1 if the column doesn't exist in the collection.</returns>
356 public int IndexOf(string columnName)
359 DataColumn column = this[columnName];
363 return IndexOf(column);
372 /// Raises the OnCollectionChanged event.
374 /// <param name="ccevent">A CollectionChangeEventArgs that contains the event data.</param>
375 protected virtual void OnCollectionChanged(CollectionChangeEventArgs ccevent)
377 if (CollectionChanged != null)
379 CollectionChanged(this, ccevent);
384 /// Raises the OnCollectionChanging event.
386 /// <param name="ccevent">A CollectionChangeEventArgs that contains the event data.</param>
387 protected internal virtual void OnCollectionChanging(CollectionChangeEventArgs ccevent)
389 if (CollectionChanged != null)
391 //FIXME: this is not right
392 //CollectionChanged(this, ccevent);
393 throw new NotImplementedException();
398 /// Removes the specified DataColumn object from the collection.
400 /// <param name="column">The DataColumn to remove.</param>
401 public void Remove(DataColumn column)
403 //TODO: can remove first with exceptions
404 //and OnChanging Event
405 CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Remove, this);
406 base.List.Remove(column);
407 OnCollectionChanged(e);
412 /// Removes the DataColumn object with the specified name from the collection.
414 /// <param name="name">The name of the column to remove.</param>
415 public void Remove(string name)
417 //TODO: can remove first with exceptions
418 //and OnChanging Event
419 DataColumn column = this[name];
420 CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Remove, this);
421 base.List.Remove(column);
422 OnCollectionChanged(e);
427 /// Removes the column at the specified index from the collection.
429 /// <param name="index">The index of the column to remove.</param>
430 public void RemoveAt(int index)
432 //TODO: can remove first with exceptions
433 //and OnChanging Event
434 CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Remove, this);
435 base.List.RemoveAt(index);
436 OnCollectionChanged(e);
441 /// Occurs when the columns collection changes, either by adding or removing a column.
443 public event CollectionChangeEventHandler CollectionChanged;