importing messaging-2008 branch to trunk [continued]
[mono.git] / mcs / class / System.Data / System.Data / DataRelationCollection.cs
index 097ff94621ca33e5ba964ae161ea7c8cf26ad3b6..799bcbde28c410de811dea91e11feff316236437 100644 (file)
 // distribute, sublicense, and/or sell copies of the Software, and to
 // permit persons to whom the Software is furnished to do so, subject to
 // the following conditions:
-// 
+//
 // The above copyright notice and this permission notice shall be
 // included in all copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -43,19 +43,21 @@ namespace System.Data {
        /// <summary>
        /// Represents the collection of DataRelation objects for this DataSet.
        /// </summary>
-       [Editor]
+       [Editor ("Microsoft.VSDesigner.Data.Design.DataRelationCollectionEditor, " + Consts.AssemblyMicrosoft_VSDesigner,
+                "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
        [DefaultEvent ("CollectionChanged")]
        [DefaultProperty ("Table")]
+#if !NET_2_0
        [Serializable]
-       public abstract class DataRelationCollection : InternalDataCollectionBase
-       {
+#endif
+       public abstract class DataRelationCollection : InternalDataCollectionBase {
                /// <summary>
                /// Summary description for DataTableRelationCollection.
                /// </summary>
-               internal class DataSetRelationCollection : DataRelationCollection
-               {
+               internal class DataSetRelationCollection : DataRelationCollection {
                        private DataSet dataSet;
-                       
+                       DataRelation [] mostRecentRelations;
+
                        /// <summary>
                        /// Initializes a new instance of the DataSetRelationCollection class.
                        /// </summary>
@@ -64,32 +66,7 @@ namespace System.Data {
                                this.dataSet = dataSet;
                        }
 
-                       /// <summary>
-                       /// Gets the DataRelation object specified by name.
-                       /// </summary>
-                       public override DataRelation this [string name]
-                       {
-                               get {
-                                       int index = IndexOf (name, true);
-                                       return index < 0 ? null : (DataRelation) List[index];
-                               }
-                       }
-
-                       /// <summary>
-                       /// Gets the DataRelation object at the specified index.
-                       /// </summary>
-                       public override DataRelation this [int index]
-                       {
-                               get {
-                                       try {
-                                               return List [index] as DataRelation;
-                                       } catch (ArgumentOutOfRangeException e) {
-                                               throw new IndexOutOfRangeException (String.Format ("Cannot find relation {0}.", index));
-                                       }
-                               }
-                       }
-
-                       protected override DataSet GetDataSet()
+                       protected override DataSet GetDataSet ()
                        {
                                return dataSet;
                        }
@@ -100,30 +77,19 @@ namespace System.Data {
                        /// <param name="relation">The relation to check.</param>
                        protected override void AddCore (DataRelation relation)
                        {
-                                if (relation.ChildTable.DataSet != this.dataSet 
-                                     || relation.ParentTable.DataSet != this.dataSet)
-                                  throw new DataException ();
-                                relation.SetDataSet (dataSet);
-                                relation.ParentTable.ChildRelations.Add (relation);
-                                relation.ChildTable.ParentRelations.Add (relation);
-                                 base.AddCore (relation);
-                        }
-
-                       public override void AddRange (DataRelation[] relations)
-                       {
-                               base.AddRange (relations);
-                       }
-
-                       public override void Clear ()
-                       {
-                               for (int i = 0; i < Count; i++)
-                                       RemoveCore(this[i]);
-
-                               base.Clear();
+                               if (relation.ChildTable.DataSet != dataSet || relation.ParentTable.DataSet != dataSet)
+                                  throw new DataException ();
+
+                               base.AddCore (relation);
+                               relation.ParentTable.ChildRelations.Add (relation);
+                               relation.ChildTable.ParentRelations.Add (relation);
+                               relation.SetDataSet (dataSet);
+                               relation.UpdateConstraints ();
                        }
 
                        protected override void RemoveCore (DataRelation relation)
                        {
+                               base.RemoveCore (relation);
                                relation.SetDataSet (null);
                                relation.ParentTable.ChildRelations.Remove (relation);
                                relation.ChildTable.ParentRelations.Remove (relation);
@@ -131,9 +97,58 @@ namespace System.Data {
                                relation.SetChildKeyConstraint (null);
                        }
 
+                       public override void AddRange (DataRelation [] relations)
+                       {
+                               if (relations == null)
+                                       return;
+
+                               if (dataSet != null && dataSet.InitInProgress){
+                                       mostRecentRelations = relations;
+                                       return;
+                               }
+
+                               foreach (DataRelation rel in relations){
+                                       if (rel == null)
+                                               continue;
+                                       Add (rel);
+                               }
+                       }
+
+                       internal override void PostAddRange ()
+                       {
+                               if (mostRecentRelations == null)
+                                       return;
+
+                               foreach (DataRelation rel in mostRecentRelations){
+                                       if (rel == null)
+                                               continue;
+                                       if (rel.InitInProgress)
+                                               rel.FinishInit (dataSet);
+                                       Add (rel);
+                               }
+                               mostRecentRelations = null;
+                       }
+
                        protected override ArrayList List {
+                               get { return base.List; }
+                       }
+
+                       public override DataRelation this [string name] {
                                get {
-                                       return base.List;
+                                       int index = IndexOf (name, true);
+                                       return index < 0 ? null : (DataRelation) List [index];
+                               }
+                       }
+
+                       /// <summary>
+                       /// Gets the DataRelation object at the specified index.
+                       /// </summary>
+                       public override DataRelation this [int index] {
+                               get {
+                                       if (index < 0 || index >= List.Count)
+                                               throw new IndexOutOfRangeException (String.Format ("Cannot find relation {0}.", index));
+
+                                       return (DataRelation) List [index];
                                }
                        }
                }
@@ -141,10 +156,9 @@ namespace System.Data {
                /// <summary>
                /// Summary description for DataTableRelationCollection.
                /// </summary>
-               internal class DataTableRelationCollection : DataRelationCollection
-               {
+               internal class DataTableRelationCollection : DataRelationCollection {
                        private DataTable dataTable;
-                       
+
                        /// <summary>
                        /// Initializes a new instance of the DataTableRelationCollection class.
                        /// </summary>
@@ -153,34 +167,28 @@ namespace System.Data {
                                this.dataTable = dataTable;
                        }
 
-                       /// <summary>
-                       /// Gets the DataRelation object specified by name.
-                       /// </summary>
-                       public override DataRelation this [string name]
+                       protected override DataSet GetDataSet ()
                        {
+                               return dataTable.DataSet;
+                       }
+
+                       public override DataRelation this [string name] {
                                get {
                                        int index = IndexOf (name, true);
-                                       return index < 0 ? null : (DataRelation) List[index];
+                                       return index < 0 ? null : (DataRelation) List [index];
                                }
                        }
 
                        /// <summary>
                        /// Gets the DataRelation object at the specified index.
                        /// </summary>
-                       public override DataRelation this [int index]
-                       {
+                       public override DataRelation this [int index] {
                                get {
-                                       try {
-                                               return List [index] as DataRelation;
-                                       } catch (ArgumentOutOfRangeException e) {
+                                       if (index < 0 || index >= List.Count)
                                                throw new IndexOutOfRangeException (String.Format ("Cannot find relation {0}.", index));
-                                       }
-                               }
-                       }
 
-                       protected override DataSet GetDataSet()
-                       {
-                               return dataTable.DataSet;
+                                       return (DataRelation) List [index];
+                               }
                        }
 
                        /// <summary>
@@ -189,66 +197,65 @@ namespace System.Data {
                        /// <param name="relation">The relation to check.</param>
                        protected override void AddCore (DataRelation relation)
                        {
-                                if (dataTable.ParentRelations == this && relation.ChildTable != dataTable)
-                                                throw new ArgumentException ("Cannot add a relation to this table's " +
-                                                                             "ParentRelations where this table is not" +
-                                                                             " the Child table.");
-
-                                if (dataTable.ChildRelations == this && relation.ParentTable != dataTable)   
-                                                throw new ArgumentException("Cannot add a relation to this table's " +
-                                                                            "ChildRelations where this table is not" +
-                                                                            " the Parent table.");
-                                
-                                base.AddCore (relation);
-
+                               if (dataTable.ParentRelations == this && relation.ChildTable != dataTable)
+                                       throw new ArgumentException ("Cannot add a relation to this table's " +
+                                                                    "ParentRelations where this table is not" +
+                                                                    " the Child table.");
+
+                               if (dataTable.ChildRelations == this && relation.ParentTable != dataTable)
+                                       throw new ArgumentException("Cannot add a relation to this table's " +
+                                                                   "ChildRelations where this table is not" +
+                                                                   " the Parent table.");
+
+                               dataTable.DataSet.Relations.Add (relation);
+                               base.AddCore (relation);
                        }
-                        
+
                        protected override void RemoveCore (DataRelation relation)
                        {
+                               relation.DataSet.Relations.Remove(relation);
                                base.RemoveCore (relation);
                        }
 
                        protected override ArrayList List {
-                               get {
-                                       return base.List;
-                               }
+                               get { return base.List; }
                        }
                }
 
-               private int defaultNameIndex;
-               private bool inTransition;
+               private DataRelation inTransition;
                int index;
 
-               
+
                /// <summary>
                /// Initializes a new instance of the DataRelationCollection class.
                /// </summary>
-               protected DataRelationCollection () 
-                       : base ()
+               protected DataRelationCollection ()
                {
-                       defaultNameIndex = 1;
-                       inTransition = false;
+                       inTransition = null;
                }
 
                /// <summary>
                /// Gets the DataRelation object specified by name.
                /// </summary>
-               public abstract DataRelation this[string name]{get;}
+               public abstract DataRelation this [string name] {
+                       get;
+               }
 
                /// <summary>
                /// Gets the DataRelation object at the specified index.
                /// </summary>
-               public abstract DataRelation this[int index]{get;}
+               public abstract DataRelation this [int index] {
+                       get;
+               }
+
 
-               
                #region Add Methods
                private string GetNextDefaultRelationName ()
                {
                        int index = 1;
-                       string defRelationName = "Relation" +index;
-                       for (; Contains (defRelationName); ++index) {
+                       string defRelationName = "Relation" + index;
+                       for (; Contains (defRelationName); ++index)
                                defRelationName = "Relation" + index;
-                       }
                        return defRelationName;
                }
 
@@ -256,37 +263,33 @@ namespace System.Data {
                /// Adds a DataRelation to the DataRelationCollection.
                /// </summary>
                /// <param name="relation">The DataRelation to add to the collection.</param>
-               [MonoTODO]
-               public void Add(DataRelation relation)
+               public void Add (DataRelation relation)
                {
-                        if (relation == null) {
-                               //TODO: Issue a good exception message.
-                               throw new ArgumentNullException();
-                       }
-                       if(List.IndexOf(relation) != -1) {
-                               //TODO: Issue a good exception message.
-                               throw new ArgumentException();
-                       }
+                       // To prevent endless recursion
+                       if (inTransition == relation)
+                               return;
 
-                       // check if the collection has a relation with the same name.
-                       int tmp = IndexOf(relation.RelationName);
-                       // if we found a relation with same name we have to check
-                       // that it is the same case.
-                       // indexof can return a table with different case letters.
-                       if (tmp != -1 &&
-                               relation.RelationName == this[tmp].RelationName)
-                                       throw new DuplicateNameException("A DataRelation named '" + relation.RelationName + "' already belongs to this DataSet.");
-                        
-
-                       this.AddCore (relation);
-                       if(relation.RelationName == string.Empty)
-                               relation.RelationName = GenerateRelationName();
-                       CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Add, this);
-                       //List.Add(relation);
-                       OnCollectionChanged(e);
+                       inTransition = relation;
+
+                       try {
+                               CollectionChangeEventArgs e = new CollectionChangeEventArgs (CollectionChangeAction.Add, this);
+                               OnCollectionChanging (e);
+
+                               this.AddCore (relation);
+                               if (relation.RelationName == string.Empty)
+                                       relation.RelationName = GenerateRelationName ();
+
+                               relation.ParentTable.ResetPropertyDescriptorsCache ();
+                               relation.ChildTable.ResetPropertyDescriptorsCache ();
+
+                               e = new CollectionChangeEventArgs (CollectionChangeAction.Add, this);
+                               OnCollectionChanged (e);
+                       } finally {
+                               inTransition = null;
+                       }
                }
 
-               private string GenerateRelationName()
+               private string GenerateRelationName ()
                {
                        index++;
                        return "Relation" + index;
@@ -301,10 +304,10 @@ namespace System.Data {
                /// <param name="parentColumn">parent column of relation.</param>
                /// <param name="childColumn">child column of relation.</param>
                /// <returns>The created DataRelation.</returns>
-               public virtual DataRelation Add(DataColumn parentColumn, DataColumn childColumn)
-               {       
-                       DataRelation dataRelation = new DataRelation(GetNextDefaultRelationName (), parentColumn, childColumn);
-                       Add(dataRelation);
+               public virtual DataRelation Add (DataColumn parentColumn, DataColumn childColumn)
+               {
+                       DataRelation dataRelation = new DataRelation (GetNextDefaultRelationName (), parentColumn, childColumn);
+                       Add (dataRelation);
                        return dataRelation;
                }
 
@@ -317,10 +320,10 @@ namespace System.Data {
                /// <param name="parentColumns">An array of parent DataColumn objects.</param>
                /// <param name="childColumns">An array of child DataColumn objects.</param>
                /// <returns>The created DataRelation.</returns>
-               public virtual DataRelation Add(DataColumn[] parentColumns, DataColumn[] childColumns)
+               public virtual DataRelation Add (DataColumn [] parentColumns, DataColumn [] childColumns)
                {
-                       DataRelation dataRelation = new DataRelation(GetNextDefaultRelationName (), parentColumns, childColumns);
-                       Add(dataRelation);
+                       DataRelation dataRelation = new DataRelation (GetNextDefaultRelationName (), parentColumns, childColumns);
+                       Add (dataRelation);
                        return dataRelation;
                }
 
@@ -335,13 +338,14 @@ namespace System.Data {
                /// <param name="parentColumn">parent column of relation.</param>
                /// <returns>The created DataRelation.</returns>
                /// <returns></returns>
-               public virtual DataRelation Add(string name, DataColumn parentColumn, DataColumn childColumn)
+               public virtual DataRelation Add (string name, DataColumn parentColumn, DataColumn childColumn)
                {
                        //If no name was supplied, give it a default name.
-                       if (name == null || name == "") name = GetNextDefaultRelationName ();
+                       if (name == null || name == "")
+                               name = GetNextDefaultRelationName ();
 
-                       DataRelation dataRelation = new DataRelation(name, parentColumn, childColumn);
-                       Add(dataRelation);
+                       DataRelation dataRelation = new DataRelation (name, parentColumn, childColumn);
+                       Add (dataRelation);
                        return dataRelation;
                }
 
@@ -352,13 +356,14 @@ namespace System.Data {
                /// <param name="parentColumns">An array of parent DataColumn objects.</param>
                /// <param name="childColumns">An array of child DataColumn objects.</param>
                /// <returns>The created DataRelation.</returns>
-               public virtual DataRelation Add(string name, DataColumn[] parentColumns, DataColumn[] childColumns)
+               public virtual DataRelation Add (string name, DataColumn [] parentColumns, DataColumn [] childColumns)
                {
                        //If no name was supplied, give it a default name.
-                       if (name == null || name == "") name = GetNextDefaultRelationName ();
+                       if (name == null || name == "")
+                               name = GetNextDefaultRelationName ();
 
-                       DataRelation dataRelation = new DataRelation(name, parentColumns, childColumns);
-                       Add(dataRelation);
+                       DataRelation dataRelation = new DataRelation (name, parentColumns, childColumns);
+                       Add (dataRelation);
                        return dataRelation;
                }
 
@@ -377,15 +382,16 @@ namespace System.Data {
                public virtual DataRelation Add(string name, DataColumn parentColumn, DataColumn childColumn, bool createConstraints)
                {
                        //If no name was supplied, give it a default name.
-                       if (name == null || name == "") name = GetNextDefaultRelationName ();
+                       if (name == null || name == "")
+                               name = GetNextDefaultRelationName ();
 
-                       DataRelation dataRelation = new DataRelation(name, parentColumn, childColumn, createConstraints);
-                       Add(dataRelation);
+                       DataRelation dataRelation = new DataRelation (name, parentColumn, childColumn, createConstraints);
+                       Add (dataRelation);
                        return dataRelation;
                }
 
                /// <summary>
-               /// Creates a DataRelation with the specified name, arrays of parent and child columns, 
+               /// Creates a DataRelation with the specified name, arrays of parent and child columns,
                /// and value specifying whether to create a constraint, and adds it to the collection.
                /// </summary>
                /// <param name="name">The name of the DataRelation to create.</param>
@@ -393,65 +399,134 @@ namespace System.Data {
                /// <param name="childColumns">An array of child DataColumn objects.</param>
                /// <param name="createConstraints">true to create a constraint; otherwise false.</param>
                /// <returns>The created DataRelation.</returns>
-               public virtual DataRelation Add(string name, DataColumn[] parentColumns, DataColumn[] childColumns, bool createConstraints)
+               public virtual DataRelation Add (string name, DataColumn [] parentColumns, DataColumn [] childColumns, bool createConstraints)
                {
                        //If no name was supplied, give it a default name.
-                       if (name == null || name == "") name = GetNextDefaultRelationName ();
+                       if (name == null || name == "")
+                               name = GetNextDefaultRelationName ();
 
-                       DataRelation dataRelation = new DataRelation(name, parentColumns, childColumns, createConstraints);
-                       Add(dataRelation);
+                       DataRelation dataRelation = new DataRelation (name, parentColumns, childColumns, createConstraints);
+                       Add (dataRelation);
                        return dataRelation;
                }
                #endregion
-       
+
                /// <summary>
                /// Adds to the list
                /// </summary>
                /// <param name="relation">The relation to check.</param>
-               [MonoTODO]
-               protected virtual void AddCore(DataRelation relation)
+               protected virtual void AddCore (DataRelation relation)
                {
-                        relation.UpdateConstraints ();
-                       List.Add(relation);
+                       if (relation == null)
+                               //TODO: Issue a good exception message.
+                               throw new ArgumentNullException();
+
+                       if(List.IndexOf (relation) != -1)
+                               //TODO: Issue a good exception message.
+                               throw new ArgumentException();
+
+                       // check if the collection has a relation with the same name.
+                       int tmp = IndexOf (relation.RelationName);
+                       // if we found a relation with same name we have to check
+                       // that it is the same case.
+                       // indexof can return a table with different case letters.
+                       if (tmp != -1 && relation.RelationName == this [tmp].RelationName)
+                               throw new DuplicateNameException("A DataRelation named '" + relation.RelationName + "' already belongs to this DataSet.");
+
+                       // check whether the relation exists between the columns already
+                       foreach (DataRelation rel in this) {
+                               // compare child columns
+                               bool differs = false;
+                               foreach (DataColumn current in relation.ChildColumns) {
+                                       bool exists = false;
+                                       foreach (DataColumn col in rel.ChildColumns) {
+                                               if (col == current) {
+                                                       exists = true;
+                                                       break;
+                                               }
+                                       }
+                                       if (!exists) {
+                                               differs = true;
+                                               break;
+                                       }
+                               }
+
+                               if (! differs) {
+                                       // compare parent columns
+                                       differs = false;
+                                       foreach (DataColumn current in relation.ParentColumns) {
+                                               bool exists = false;
+                                               foreach (DataColumn col in rel.ParentColumns) {
+                                                       if (col == current) {
+                                                               exists = true;
+                                                               break;
+                                                       }
+                                               }
+                                               if (!exists) {
+                                                       differs = true;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (! differs)
+                                               throw new ArgumentException ("A relation already exists for these child columns");
+                               }
+                       }
+
+                       // Add to collection
+                       List.Add (relation);
                }
-                
-                /// <summary>
+
+               /// <summary>
                /// Copies the elements of the specified DataRelation array to the end of the collection.
                /// </summary>
                /// <param name="relations">The array of DataRelation objects to add to the collection.</param>
-               public virtual void AddRange(DataRelation[] relations)
+               public virtual void AddRange (DataRelation[] relations)
+               {
+                       if (relations == null)
+                               return;
+
+                       foreach (DataRelation relation in relations)
+                               Add (relation);
+               }
+
+#if NET_2_0
+               public void CopyTo (DataRelation [] array, int index)
                {
-                       foreach (DataRelation relation in relations) Add(relation);
+                       CopyTo ((Array) array, index);
                }
+#endif
 
-               public virtual bool CanRemove(DataRelation relation)
+               internal virtual void PostAddRange ()
                {
-                       if (relation == null || !GetDataSet().Equals(relation.DataSet))
+               }
+
+               public virtual bool CanRemove (DataRelation relation)
+               {
+                       if (relation == null || !GetDataSet ().Equals (relation.DataSet))
                                return false;
 
                        // check if the relation doesnot belong to this collection
-                        int tmp = IndexOf(relation.RelationName);
-                        // if we found a relation with same name we have to check
-                        // that it is the same case.
-                        // indexof can return a table with different case letters.
-                        if (tmp != -1) {
-                               if(relation.RelationName != this[tmp].RelationName)
-                                        return false;
-                        }
-                        else {
-                                return false;
-                        }                                       
-                                                                                        
-                        return true;
+                       int tmp = IndexOf (relation.RelationName);
+                       return tmp != -1 && relation.RelationName == this [tmp].RelationName;
                }
 
-               public virtual void Clear()
+               public virtual void Clear ()
                {
-                       List.Clear();
+                       for (int i = 0; i < Count; i++)
+                               Remove (this [i]);
+
+                       List.Clear ();
                }
 
-               public virtual bool Contains(string name)
+               public virtual bool Contains (string name)
                {
+                       DataSet tmpDataSet = GetDataSet ();
+                       if (tmpDataSet != null) {
+                               DataRelation tmpRelation = tmpDataSet.Relations [name];
+                               if (tmpRelation != null)
+                                       return true;
+                       }
                        return (-1 != IndexOf (name, false));
                }
 
@@ -460,26 +535,24 @@ namespace System.Data {
                        return new CollectionChangeEventArgs (action, this);
                }
 
-               protected abstract DataSet GetDataSet();
+               protected abstract DataSet GetDataSet ();
 
-               public virtual int IndexOf(DataRelation relation)
+               public virtual int IndexOf (DataRelation relation)
                {
-                       return List.IndexOf(relation);
+                       return List.IndexOf (relation);
                }
 
-               public virtual int IndexOf(string relationName)
+               public virtual int IndexOf (string relationName)
                {
-                       return IndexOf(relationName, false);
+                       return IndexOf (relationName, false);
                }
 
                private int IndexOf (string name, bool error)
                {
                        int count = 0, match = -1;
-                       for (int i = 0; i < List.Count; i++)
-                       {
+                       for (int i = 0; i < List.Count; i++) {
                                String name2 = ((DataRelation) List[i]).RelationName;
-                               if (String.Compare (name, name2, true) == 0)
-                               {
+                               if (String.Compare (name, name2, true) == 0) {
                                        if (String.Compare (name, name2, false) == 0)
                                                return i;
                                        match = i;
@@ -499,45 +572,62 @@ namespace System.Data {
                                CollectionChanged (this, ccevent);
                }
 
-               [MonoTODO]
-               protected internal virtual void OnCollectionChanging (CollectionChangeEventArgs ccevent)
+               protected virtual void OnCollectionChanging (CollectionChangeEventArgs ccevent)
                {
-                       throw new NotImplementedException ();
+                       // LAME Spec: No associated events and it doesn't update CollectionChanged
+                       // event too as specified in MSDN
+                       // throw new NotImplementedException ();
                }
 
                public void Remove (DataRelation relation)
                {
+                       // To prevent endless recursion
+                       if (inTransition == relation)
+                               return;
+
+                       inTransition = relation;
+
                        if (relation == null)
                                return;
 
-                        // check if the list doesnot contains this relation.
-                        if (!(List.Contains(relation)))
-                                throw new ArgumentException("Relation doesnot belong to this Collection.");
+                       try {
+                               // check if the list doesnot contains this relation.
+                               if (!(List.Contains (relation)))
+                                       throw new ArgumentException ("Relation doesnot belong to this Collection.");
 
-                       RemoveCore (relation);
-                       List.Remove (relation);
-                       string name = "Relation" + index;
-                       if (relation.RelationName == name)
-                               index--;
-                       OnCollectionChanged (CreateCollectionChangeEvent (CollectionChangeAction.Remove));
+                               OnCollectionChanging (CreateCollectionChangeEvent (CollectionChangeAction.Remove));
+
+                               RemoveCore (relation);
+                               string name = "Relation" + index;
+                               if (relation.RelationName == name)
+                                       index--;
+
+                               OnCollectionChanged (CreateCollectionChangeEvent (CollectionChangeAction.Remove));
+                       } finally {
+                               inTransition = null;
+                       }
                }
 
                public void Remove (string name)
                {
-                       Remove ((DataRelation) List[IndexOf (name)]);
+                       DataRelation relation = this [name];
+                       if (relation == null)
+                               throw new ArgumentException ("Relation doesnot belong to this Collection.");
+                       Remove (relation);
                }
 
                public void RemoveAt (int index)
                {
-                       if (( index < 0 ) || (index >=List.Count))
-                                throw new IndexOutOfRangeException ("There is no row at position " + index + ".");
-                       Remove(this[index]);
+                       DataRelation relation = this [index];
+                       if (relation == null)
+                               throw new IndexOutOfRangeException (String.Format ("Cannot find relation {0}", index));
+                       Remove (relation);
                }
 
-               [MonoTODO]
-               protected virtual void RemoveCore(DataRelation relation)
+               protected virtual void RemoveCore (DataRelation relation)
                {
-                       // TODO: What have to be done?
+                       // Remove from collection
+                       List.Remove (relation);
                }
 
                #region Events