2003-02-18 Alan Tam <Tam@SiuLung.com>
[mono.git] / mcs / class / System.Data / System.Data / DataTable.cs
1 //
2 // System.Data.DataTable.cs
3 //
4 // Author:
5 //   Franklin Wise <gracenote@earthlink.net>
6 //   Christopher Podurgiel (cpodurgiel@msn.com)
7 //   Daniel Morgan <danmorg@sc.rr.com>
8 //   Rodrigo Moya <rodrigo@ximian.com>
9 //   Tim Coleman (tim@timcoleman.com)
10 //   Ville Palo <vi64pa@koti.soon.fi>
11 //
12 // (C) Chris Podurgiel
13 // (C) Ximian, Inc 2002
14 // Copyright (C) Tim Coleman, 2002
15 //
16
17 using System;
18 using System.Collections;
19 using System.ComponentModel;
20 using System.Globalization;
21 using System.Runtime.Serialization;
22
23 namespace System.Data {
24         [Designer]
25         [ToolboxItem (false)]
26         [DefaultEvent ("RowChanging")]
27         [DefaultProperty ("TableName")]
28         [DesignTimeVisible (false)]
29         [Serializable]
30         public class DataTable : MarshalByValueComponent, IListSource, ISupportInitialize, ISerializable        
31         {
32                 internal DataSet dataSet;   
33                 
34                 private bool _caseSensitive;
35                 private DataColumnCollection _columnCollection;
36                 private ConstraintCollection _constraintCollection;
37                 private DataView _defaultView;
38
39                 private string _displayExpression;
40                 private PropertyCollection _extendedProperties;
41                 private bool _hasErrors;
42                 private CultureInfo _locale;
43                 private int _minimumCapacity;
44                 private string _nameSpace;
45                 private DataRelationCollection _childRelations; 
46                 private DataRelationCollection _parentRelations;
47                 private string _prefix;
48                 private DataColumn[] _primaryKey;
49                 private DataRowCollection _rows;
50                 private ISite _site;
51                 private string _tableName;
52                 private bool _containsListCollection;
53                 private string _encodedTableName;
54                 
55                 /// <summary>
56                 /// Initializes a new instance of the DataTable class with no arguments.
57                 /// </summary>
58                 
59                 public DataTable()
60                 {
61                         dataSet = null;
62                         _columnCollection = new DataColumnCollection(this);
63                         _constraintCollection = new ConstraintCollection(); 
64                         _extendedProperties = new PropertyCollection();
65                         _tableName = "";
66                         _nameSpace = null;
67                         _caseSensitive = false;         //default value
68                         _displayExpression = null;
69                         _primaryKey = null;
70                         _site = null;
71                         _rows = new DataRowCollection (this);
72                         _locale = CultureInfo.CurrentCulture;
73
74                         //LAMESPEC: spec says 25 impl does 50
75                         _minimumCapacity = 50;
76                         
77                         _childRelations = new DataRelationCollection.DataTableRelationCollection (this);
78                         _parentRelations = new DataRelationCollection.DataTableRelationCollection (this);
79
80                 
81                         _defaultView = new DataView(this);
82                 }
83
84                 /// <summary>
85                 /// Intitalizes a new instance of the DataTable class with the specified table name.
86                 /// </summary>
87                 
88                 public DataTable(string tableName) : this ()
89                 {
90                         _tableName = tableName;
91                 }
92
93                 /// <summary>
94                 /// Initializes a new instance of the DataTable class with the SerializationInfo and the StreamingContext.
95                 /// </summary>
96                 
97                 [MonoTODO]
98                 protected DataTable(SerializationInfo info, StreamingContext context)
99                         : this ()
100                 {
101                         //
102                         // TODO: Add constructor logic here
103                         //
104                 }
105
106                 /// <summary>
107                 /// Indicates whether string comparisons within the table are case-sensitive.
108                 /// </summary>
109                 [DataSysDescription ("Indicates whether comparing strings within the table is case sensitive.")]        
110                 public bool CaseSensitive {
111                         get { return _caseSensitive; }
112                         set { _caseSensitive = value; }
113                 }
114
115
116                 internal void ChangedDataColumn (DataRow dr, DataColumn dc, object pv)
117                 {
118                         DataColumnChangeEventArgs e = new DataColumnChangeEventArgs (dr, dc, pv);
119                         OnColumnChanged(e);
120                 }
121
122                 internal void ChangingDataColumn (DataRow dr, DataColumn dc, object pv)
123                 {
124                         DataColumnChangeEventArgs e = new DataColumnChangeEventArgs (dr, dc, pv);
125                         OnColumnChanging (e);
126                 }
127
128                 internal void DeletedDataRow (DataRow dr, DataRowAction action)
129                 {
130                         DataRowChangeEventArgs e = new DataRowChangeEventArgs (dr, action);
131                         OnRowDeleted (e);
132                 }
133
134                 internal void ChangedDataRow (DataRow dr, DataRowAction action)
135                 {
136                         DataRowChangeEventArgs e = new DataRowChangeEventArgs (dr, action);
137                         OnRowChanged (e);
138                 }
139
140                 /// <summary>
141                 /// Gets the collection of child relations for this DataTable.
142                 /// </summary>
143                 [Browsable (false)]
144                 [DataSysDescription ("Returns the child relations for this table.")]
145                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
146                 public DataRelationCollection ChildRelations {
147                         get {
148                                 return _childRelations;
149                         }
150                 }
151
152                 /// <summary>
153                 /// Gets the collection of columns that belong to this table.
154                 /// </summary>
155                 [DataCategory ("Data")]
156                 [DataSysDescription ("The collection that holds the columns for this table.")]
157                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
158                 public DataColumnCollection Columns {
159                         get { return _columnCollection; }
160                 }
161
162                 /// <summary>
163                 /// Gets the collection of constraints maintained by this table.
164                 /// </summary>
165                 [DataCategory ("Data")] 
166                 [DataSysDescription ("The collection that holds the constraints for this table.")]
167                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
168                 public ConstraintCollection Constraints {
169                         get { return _constraintCollection; }
170                 }
171
172                 /// <summary>
173                 /// Gets the DataSet that this table belongs to.
174                 /// </summary>
175                 [Browsable (false)]
176                 [DataSysDescription ("Indicates the DataSet to which this table belongs.")]
177                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
178                 public DataSet DataSet {
179                         get { return dataSet; }
180                 }
181
182                 
183
184                 /// <summary>
185                 /// Gets a customized view of the table which may 
186                 /// include a filtered view, or a cursor position.
187                 /// </summary>
188                 [MonoTODO]      
189                 [Browsable (false)]
190                 [DataSysDescription ("This is the default DataView for the table.")]
191                 public DataView DefaultView {
192                         get { return _defaultView; }
193                 }
194                 
195
196                 /// <summary>
197                 /// Gets or sets the expression that will return 
198                 /// a value used to represent this table in the user interface.
199                 /// </summary>
200                 [DataCategory ("Data")]
201                 [DataSysDescription ("The expression used to compute the data-bound value of this row.")]       
202                 [DefaultValue ("")]
203                 public string DisplayExpression {
204                         get { return "" + _displayExpression; }
205                         set { _displayExpression = value; }
206                 }
207
208                 /// <summary>
209                 /// Gets the collection of customized user information.
210                 /// </summary>
211                 [Browsable (false)]
212                 [DataCategory ("Data")]
213                 [DataSysDescription ("The collection that holds custom user information.")]
214                 public PropertyCollection ExtendedProperties {
215                         get { return _extendedProperties; }
216                 }
217
218                 /// <summary>
219                 /// Gets a value indicating whether there are errors in 
220                 /// any of the_rows in any of the tables of the DataSet to 
221                 /// which the table belongs.
222                 /// </summary>
223                 [Browsable (false)]
224                 [DataSysDescription ("Returns whether the table has errors.")]
225                 public bool HasErrors {
226                         get { return _hasErrors; }
227                 }
228
229                 /// <summary>
230                 /// Gets or sets the locale information used to 
231                 /// compare strings within the table.
232                 /// </summary>
233                 [DataSysDescription ("Indicates a locale under which to compare strings within the table.")]
234                 public CultureInfo Locale {
235                         get { return _locale; }
236                         set { _locale = value; }
237                 }
238
239                 /// <summary>
240                 /// Gets or sets the initial starting size for this table.
241                 /// </summary>
242                 [DataCategory ("Data")]
243                 [DataSysDescription ("Indicates an initial starting size for this table.")]
244                 [DefaultValue (50)]
245                 public int MinimumCapacity {
246                         get { return _minimumCapacity; }
247                         set { _minimumCapacity = value; }
248                 }
249
250                 /// <summary>
251                 /// Gets or sets the namespace for the XML represenation 
252                 /// of the data stored in the DataTable.
253                 /// </summary>
254                 [DataCategory ("Data")]
255                 [DataSysDescription ("Indicates the XML uri namespace for the elements contained in this table.")]
256                 public string Namespace {
257                         get { return "" + _nameSpace; }
258                         set { _nameSpace = value; }
259                 }
260
261                 /// <summary>
262                 /// Gets the collection of parent relations for 
263                 /// this DataTable.
264                 /// </summary>
265                 [Browsable (false)]
266                 [DataSysDescription ("Returns the parent relations for this table.")]
267                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
268                 public DataRelationCollection ParentRelations {
269                         get {   
270                                 return _parentRelations;
271                         }
272                 }
273
274                 /// <summary>
275                 /// Gets or sets the namespace for the XML represenation
276                 ///  of the data stored in the DataTable.
277                 /// </summary>
278                 [DataCategory ("Data")]
279                 [DataSysDescription ("Indicates the Prefix of the namespace used for this table in XML representation.")]
280                 [DefaultValue ("")]
281                 public string Prefix {
282                         get { return "" + _prefix; }
283                         set { _prefix = value; }
284                 }
285
286                 /// <summary>
287                 /// Gets or sets an array of columns that function as 
288                 /// primary keys for the data table.
289                 /// </summary>
290                 [DataCategory ("Data")]
291                 [DataSysDescription ("Indicates the column(s) that represent the primary key for this table.")]
292                 public DataColumn[] PrimaryKey
293                 {
294                         get {
295                                 UniqueConstraint uc = UniqueConstraint.GetPrimaryKeyConstraint( Constraints);
296                                 if (null == uc) return new DataColumn[] {};
297                                 return uc.Columns;
298                         }
299                         set {
300
301                                 //YUK: msft removes a previous unique constraint if it is flagged as a pk  
302                                 //when a new pk is set 
303
304                                 //clear Primary Key if value == null
305                                 if (null == value)
306                                 {
307                                         UniqueConstraint.SetAsPrimaryKey(this.Constraints, null);
308                                         return;
309                                 }
310                         
311
312                                 //Does constraint exist for these columns
313                                 UniqueConstraint uc = UniqueConstraint.GetUniqueConstraintForColumnSet(
314                                                 this.Constraints, (DataColumn[]) value);
315
316                                 //if constraint doesn't exist for columns
317                                 //create new unique primary key constraint
318                                 if (null == uc)
319                                 {
320                                         uc = new UniqueConstraint( (DataColumn[]) value, true);
321                                 }
322                                 else //set existing constraint as the new primary key
323                                 {
324                                         UniqueConstraint.SetAsPrimaryKey(this.Constraints, uc);
325                                 }
326                                 
327                         }
328                 }
329
330                 /// <summary>
331                 /// Gets the collection of_rows that belong to this table.
332                 /// </summary>
333                 [Browsable (false)]
334                 [DataSysDescription ("Indicates the collection that holds the rows of data for this table.")]   
335                 public DataRowCollection Rows {
336                         get { return _rows; }
337                 }
338
339                 /// <summary>
340                 /// Gets or sets an System.ComponentModel.ISite 
341                 /// for the DataTable.
342                 /// </summary>
343                 [Browsable (false)]
344                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
345                 public override ISite Site {
346                         get { return _site; }
347                         set { _site = value; }
348                 }
349
350                 /// <summary>
351                 /// Gets or sets the name of the the DataTable.
352                 /// </summary>
353                 [DataCategory ("Data")]
354                 [DataSysDescription ("Indicates the name used to look up this table in the Tables collection of a DataSet.")]
355                 [DefaultValue ("")]     
356                 [RefreshProperties (RefreshProperties.All)]
357                 public string TableName {
358                         get { return "" + _tableName; }
359                         set { _tableName = value; }
360                 }
361                 
362                 bool IListSource.ContainsListCollection {
363                         get {
364                                 // the collection is a DataView
365                                 return false;
366                         }
367                 }
368
369                 /// <summary>
370                 /// Commits all the changes made to this table since the 
371                 /// last time AcceptChanges was called.
372                 /// </summary>
373                 
374                 public void AcceptChanges()
375                 {
376
377                         //FIXME: Do we need to validate anything here or
378                         //try to catch any errors to deal with them?
379
380                         foreach(DataRow myRow in _rows)
381                         {
382                                 myRow.AcceptChanges();
383                         }
384
385                 }
386
387                 /// <summary>
388                 /// Begins the initialization of a DataTable that is used 
389                 /// on a form or used by another component. The initialization
390                 /// occurs at runtime.
391                 /// </summary>
392                 
393                 public void BeginInit()
394                 {
395                 }
396
397                 /// <summary>
398                 /// Turns off notifications, index maintenance, and 
399                 /// constraints while loading data.
400                 /// </summary>
401                 
402                 [MonoTODO]
403                 public void BeginLoadData()
404                 {
405                 }
406
407                 /// <summary>
408                 /// Clears the DataTable of all data.
409                 /// </summary>
410                 
411                 public void Clear()
412                 {
413                         _rows.Clear ();
414                 }
415
416                 /// <summary>
417                 /// Clones the structure of the DataTable, including
418                 ///  all DataTable schemas and constraints.
419                 /// </summary>
420                 
421                 [MonoTODO]
422                 public virtual DataTable Clone()
423                 {
424                         DataTable Copy = new DataTable ();                      
425                         CopyProperties (Copy);
426                         return Copy;
427                 }
428
429                 /// <summary>
430                 /// Computes the given expression on the current_rows that 
431                 /// pass the filter criteria.
432                 /// </summary>
433                 
434                 [MonoTODO]
435                 public object Compute(string expression, string filter)
436                 {                       
437                         //FIXME: //Do a real compute
438                         object obj = "a";
439                         return obj;
440                 }
441
442                 /// <summary>
443                 /// Copies both the structure and data for this DataTable.
444                 /// </summary>
445                 [MonoTODO]      
446                 public DataTable Copy()
447                 {
448                         DataTable Copy = new DataTable ();
449
450
451                         CopyProperties (Copy);
452
453                         foreach (DataRow Row in Rows) {
454                                 DataRow NewRow = Copy.NewRow ();
455                                 NewRow.RowError = Row.RowError;
456                                 foreach (DataColumn C in Copy.Columns) {
457                                         NewRow [C.ColumnName] = Row [C.ColumnName];
458                                 }
459                                 Copy.Rows.Add (NewRow);
460                         }
461                                         
462                         return Copy;
463                 }
464
465                 [MonoTODO]
466                 private void CopyProperties (DataTable Copy)
467                 {
468                         Copy.CaseSensitive = CaseSensitive;
469                         // Copy.ChildRelations
470                         // Copy.Constraints
471                         // Copy.Container
472                         // Copy.DefaultView
473                         // Copy.DesignMode
474                         Copy.DisplayExpression = DisplayExpression;
475                         // Copy.ExtendedProperties
476                         Copy.Locale = Locale;
477                         Copy.MinimumCapacity = MinimumCapacity;
478                         Copy.Namespace = Namespace;
479                         // Copy.ParentRelations
480                         Copy.Prefix = Prefix;
481                         //Copy.PrimaryKey = PrimaryKey;
482                         Copy.Site = Site;
483                         Copy.TableName = TableName;
484
485                         // Copy columns
486                         foreach (DataColumn Column in Columns) {
487                                 Copy.Columns.Add (CopyColumn (Column));                         
488                         }
489
490                 }
491                 /// <summary>
492                 /// Ends the initialization of a DataTable that is used 
493                 /// on a form or used by another component. The 
494                 /// initialization occurs at runtime.
495                 /// </summary>
496                 
497                 public void EndInit()
498                 {
499                 }
500
501                 /// <summary>
502                 /// Turns on notifications, index maintenance, and 
503                 /// constraints after loading data.
504                 /// </summary>
505                 
506                 [MonoTODO]
507                 public void EndLoadData()
508                 {
509                 }
510
511                 /// <summary>
512                 /// Gets a copy of the DataTable that contains all
513                 ///  changes made to it since it was loaded or 
514                 ///  AcceptChanges was last called.
515                 /// </summary>
516                 [MonoTODO]
517                 public DataTable GetChanges()
518                 {
519                         //TODO:
520                         return this;
521                 }
522
523                 /// <summary>
524                 /// Gets a copy of the DataTable containing all 
525                 /// changes made to it since it was last loaded, or 
526                 /// since AcceptChanges was called, filtered by DataRowState.
527                 /// </summary>
528                 [MonoTODO]      
529                 public DataTable GetChanges(DataRowState rowStates)
530                 {
531                         //TODO:
532                         return this;
533                 }
534
535                 /// <summary>
536                 /// Gets an array of DataRow objects that contain errors.
537                 /// </summary>
538                 
539                 [MonoTODO]
540                 public DataRow[] GetErrors()
541                 {
542                         throw new NotImplementedException ();
543                 }
544
545                 /// <summary>
546                 /// This member supports the .NET Framework infrastructure
547                 /// and is not intended to be used directly from your code.
548                 /// </summary>
549                 
550                 protected virtual DataTable CreateInstance()
551                 {
552                         return Activator.CreateInstance(this.GetType(), true) as DataTable;
553                 }
554
555                 /// <summary>
556                 /// This member supports the .NET Framework infrastructure
557                 /// and is not intended to be used directly from your code.
558                 /// </summary>
559                 
560                 protected virtual Type GetRowType()
561                 {
562                         return typeof (DataRow);
563                 }
564
565                 /// <summary>
566                 /// This member supports the .NET Framework infrastructure 
567                 /// and is not intended to be used directly from your code.
568                 /// 
569                 /// Used for Data Binding between System.Web.UI. controls 
570                 /// like a DataGrid
571                 /// or
572                 /// System.Windows.Forms controls like a DataGrid
573                 /// </summary>
574                 IList IListSource.GetList()
575                 {
576                         IList list = (IList) _defaultView;
577                         return list;
578                 }
579                                 
580                 /// <summary>
581                 /// Copies a DataRow into a DataTable, preserving any 
582                 /// property settings, as well as original and current values.
583                 /// </summary>
584                 [MonoTODO]
585                 public void ImportRow(DataRow row)
586                 {
587                 }
588
589                 /// <summary>
590                 /// This member supports the .NET Framework infrastructure
591                 ///  and is not intended to be used directly from your code.
592                 /// </summary>
593                 
594                 [MonoTODO]
595                 void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
596                 {
597                 }
598
599                 /// <summary>
600                 /// Finds and updates a specific row. If no matching row
601                 ///  is found, a new row is created using the given values.
602                 /// </summary>
603                 [MonoTODO]
604                 public DataRow LoadDataRow(object[] values, bool fAcceptChanges)
605                 {
606                         DataRow row = null;
607                         if (PrimaryKey.Length == 0) {
608                                 row = Rows.Add (values);
609                                 if (fAcceptChanges)
610                                         row.AcceptChanges ();
611                         }
612                         else
613                                 throw new NotImplementedException ();
614                         return row;
615                 }
616
617                 /// <summary>
618                 /// Creates a new DataRow with the same schema as the table.
619                 /// </summary>
620                 public DataRow NewRow()
621                 {
622                         return this.NewRowFromBuilder (new DataRowBuilder (this, 0, 0));
623                 }
624
625                 /// <summary>
626                 /// This member supports the .NET Framework infrastructure
627                 ///  and is not intended to be used directly from your code.
628                 /// </summary>
629                 protected internal DataRow[] NewRowArray(int size)
630                 {
631                         return (DataRow[]) Array.CreateInstance (GetRowType(), size);
632                 }
633
634                 /// <summary>
635                 /// Creates a new row from an existing row.
636                 /// </summary>
637                 
638                 protected virtual DataRow NewRowFromBuilder(DataRowBuilder builder)
639                 {
640                         return new DataRow (builder);
641                 }
642         
643
644                 /// <summary>
645                 /// Rolls back all changes that have been made to the 
646                 /// table since it was loaded, or the last time AcceptChanges
647                 ///  was called.
648                 /// </summary>
649                 
650                 [MonoTODO]
651                 public void RejectChanges()
652                 {
653                         
654                         //foreach(DataRow myRow in _rows)
655                         //{
656                         for (int i = _rows.Count - 1; i >= 0; i--) {
657                                 DataRow row = _rows [i];
658                                 if (row.RowState != DataRowState.Unchanged)
659                                         _rows [i].RejectChanges ();
660                         }
661                 }
662
663                 /// <summary>
664                 /// Resets the DataTable to its original state.
665                 /// </summary>
666                 
667                 [MonoTODO]
668                 public virtual void Reset()
669                 {
670                 }
671
672                 /// <summary>
673                 /// Gets an array of all DataRow objects.
674                 /// </summary>
675                 
676                 [MonoTODO]
677                 public DataRow[] Select()
678                 {
679                         //FIXME:
680                         DataRow[] dataRows = {null};
681                         return dataRows;
682                 }
683
684                 /// <summary>
685                 /// Gets an array of all DataRow objects that match 
686                 /// the filter criteria in order of primary key (or 
687                 /// lacking one, order of addition.)
688                 /// </summary>
689                 
690                 [MonoTODO]
691                 public DataRow[] Select(string filterExpression)
692                 {
693                         ExpressionElement Expression = new ExpressionMainElement (filterExpression);
694
695                         ArrayList List = new ArrayList ();
696                         foreach (DataRow Row in Rows) {
697                                 
698                                 if (Expression.Test (Row))
699                                         List.Add (Row);
700                         }
701                         
702                         return (DataRow [])List.ToArray (typeof (DataRow));
703                 }
704
705                 /// <summary>
706                 /// Gets an array of all DataRow objects that 
707                 /// match the filter criteria, in the the 
708                 /// specified sort order.
709                 /// </summary>
710                 [MonoTODO]
711                 public DataRow[] Select(string filterExpression, string sort)
712                 {
713                         DataRow[] dataRows = {null};
714                         return dataRows;
715                 }
716
717                 /// <summary>
718                 /// Gets an array of all DataRow objects that match
719                 /// the filter in the order of the sort, that match 
720                 /// the specified state.
721                 /// </summary>
722                 [MonoTODO]
723                 public DataRow[] Select(string filterExpression, string sort, DataViewRowState recordStates)
724                 {
725                         DataRow[] dataRows = {null};
726                         return dataRows;
727                 }
728
729                 /// <summary>
730                 /// Gets the TableName and DisplayExpression, if 
731                 /// there is one as a concatenated string.
732                 /// </summary>
733                 public override string ToString()
734                 {
735                         //LAMESPEC: spec says concat the two. impl puts a 
736                         //plus sign infront of DisplayExpression
737                         return TableName + " " + DisplayExpression;
738                 }
739
740                 
741                 #region Events /////////////////
742                 
743                 /// <summary>
744                 /// Raises the ColumnChanged event.
745                 /// </summary>
746                 protected virtual void OnColumnChanged(DataColumnChangeEventArgs e)
747                 {
748                         if (null != ColumnChanged)
749                         {
750                                 ColumnChanged(this, e);
751                         }
752                 }
753
754                 /// <summary>
755                 /// Raises the ColumnChanging event.
756                 /// </summary>
757                 protected virtual void OnColumnChanging(DataColumnChangeEventArgs e)
758                 {
759                         if (null != ColumnChanging)
760                         {
761                                 ColumnChanging(this, e);
762                         }
763                 }
764
765                 /// <summary>
766                 /// Raises the PropertyChanging event.
767                 /// </summary>
768                 [MonoTODO]
769                 protected internal virtual void OnPropertyChanging(PropertyChangedEventArgs pcevent)
770                 {
771 //                      if (null != PropertyChanging)
772 //                      {
773 //                              PropertyChanging(this, e);
774 //                      }
775                 }
776
777                 /// <summary>
778                 /// Notifies the DataTable that a DataColumn is being removed.
779                 /// </summary>
780                 [MonoTODO]
781                 protected internal virtual void OnRemoveColumn(DataColumn column)
782                 {
783 //                      if (null != RemoveColumn)
784 //                      {
785 //                              RemoveColumn(this, e);
786 //                      }
787                 }
788
789                 /// <summary>
790                 /// Raises the RowChanged event.
791                 /// </summary>
792                 
793                 protected virtual void OnRowChanged(DataRowChangeEventArgs e)
794                 {
795                         if (null != RowChanged)
796                         {
797                                 RowChanged(this, e);
798                         }
799                 }
800
801
802                 /// <summary>
803                 /// Raises the RowChanging event.
804                 /// </summary>
805                 
806                 protected virtual void OnRowChanging(DataRowChangeEventArgs e)
807                 {
808                         if (null != RowChanging)
809                         {
810                                 RowChanging(this, e);
811                         }
812                 }
813
814                 /// <summary>
815                 /// Raises the RowDeleted event.
816                 /// </summary>
817                 protected virtual void OnRowDeleted(DataRowChangeEventArgs e)
818                 {
819                         if (null != RowDeleted)
820                         {
821                                 RowDeleted(this, e);
822                         }
823                 }
824
825                 /// <summary>
826                 /// Raises the RowDeleting event.
827                 /// </summary>
828                 protected virtual void OnRowDeleting(DataRowChangeEventArgs e)
829                 {
830                         if (null != RowDeleting)
831                         {
832                                 RowDeleting(this, e);
833                         }
834                 }
835
836                 [MonoTODO]
837                 private DataColumn CopyColumn (DataColumn Column)
838                 {
839                         DataColumn Copy = new DataColumn ();
840
841                         // Copy all the properties of column
842                         Copy.AllowDBNull = Column.AllowDBNull;
843                         Copy.AutoIncrement = Column.AutoIncrement;
844                         Copy.AutoIncrementSeed = Column.AutoIncrementSeed;
845                         Copy.AutoIncrementStep = Column.AutoIncrementStep;
846                         Copy.Caption = Column.Caption;
847                         Copy.ColumnMapping = Column.ColumnMapping;
848                         Copy.ColumnName = Column.ColumnName;
849                         // Copy.Container
850                         // Copy.DataType
851                         // Copy.DefaultValue                    
852                         Copy.Expression = Column.Expression;
853                         //Copy.ExtendedProperties
854                         Copy.MaxLength = Column.MaxLength;
855                         Copy.Namespace = Column.Namespace;
856                         Copy.Prefix = Column.Prefix;
857                         Copy.ReadOnly = Column.ReadOnly;
858                         //Copy.Site
859                         Copy.Unique = Column.Unique;
860                         
861                         return Copy;
862                 }                       
863
864                 /// <summary>
865                 /// Occurs when after a value has been changed for 
866                 /// the specified DataColumn in a DataRow.
867                 /// </summary>
868                 [DataCategory ("Data")] 
869                 [DataSysDescription ("Occurs when a value has been changed for this column.")]
870                 public event DataColumnChangeEventHandler ColumnChanged;
871
872                 /// <summary>
873                 /// Occurs when a value is being changed for the specified 
874                 /// DataColumn in a DataRow.
875                 /// </summary>
876                 [DataCategory ("Data")]
877                 [DataSysDescription ("Occurs when a value has been submitted for this column. The user can modify the proposed value and should throw an exception to cancel the edit.")]
878                 public event DataColumnChangeEventHandler ColumnChanging;
879
880                 /// <summary>
881                 /// Occurs after a DataRow has been changed successfully.
882                 /// </summary>
883                 [DataCategory ("Data")] 
884                 [DataSysDescription ("Occurs after a row in the table has been successfully edited.")]
885                 public event DataRowChangeEventHandler RowChanged;
886
887                 /// <summary>
888                 /// Occurs when a DataRow is changing.
889                 /// </summary>
890                 [DataCategory ("Data")] 
891                 [DataSysDescription ("Occurs when the row is being changed so that the event handler can modify or cancel the change. The user can modify values in the row and should throw an  exception to cancel the edit.")]
892                 public event DataRowChangeEventHandler RowChanging;
893
894                 /// <summary>
895                 /// Occurs after a row in the table has been deleted.
896                 /// </summary>
897                 [DataCategory ("Data")] 
898                 [DataSysDescription ("Occurs after a row in the table has been successfully deleted.")] 
899                 public event DataRowChangeEventHandler RowDeleted;
900
901                 /// <summary>
902                 /// Occurs before a row in the table is about to be deleted.
903                 /// </summary>
904                 [DataCategory ("Data")] 
905                 [DataSysDescription ("Occurs when a row in the table marked for deletion. Throw an exception to cancel the deletion.")]
906                 public event DataRowChangeEventHandler RowDeleting;
907                 
908                 #endregion //Events
909         }
910
911 }