Remove ChangeLog files from the repo
[mono.git] / mcs / class / System.Design / System.ComponentModel.Design / CollectionEditor.cs
index 7d0a5650d9c2a2645a0672f0ae65535a2e46199f..899edd63830213fc7a0e3a333d8f177859a462bb 100644 (file)
@@ -3,8 +3,13 @@
 //
 // Authors:
 //      Martin Willemoes Hansen (mwh@sysrq.dk)
-//
+//   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
+//      Ivan N. Zlatev (contact@i-nz.net)
+// 
 // (C) 2003 Martin Willemoes Hansen
+// (C) 2007 Andreas Nahr
+// (C) 2007 Ivan N. Zlatev
+// (C) 2008 Novell, Inc
 //
 
 //
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+
+using System;
+using System.Reflection;
+using System.Collections;
+using System.ComponentModel;
+using System.Drawing.Design;
 using System.Windows.Forms;
 using System.Windows.Forms.Design;
-using System.Drawing.Design;
 
 namespace System.ComponentModel.Design
 {
@@ -38,221 +48,692 @@ namespace System.ComponentModel.Design
        {
                protected abstract class CollectionForm : Form
                {
-                       [MonoTODO]
+                       private CollectionEditor editor;
+                       private object editValue;
+
                        public CollectionForm (CollectionEditor editor)
                        {
+                               this.editor = editor;
                        }
 
-                       public object EditValue {
-                               [MonoTODO]
-                               get { throw new NotImplementedException(); } 
+                       protected Type CollectionItemType
+                       {
+                               get { return editor.CollectionItemType; }
+                       }
 
-                               [MonoTODO]
-                               set { throw new NotImplementedException(); }
+                       protected Type CollectionType
+                       {
+                               get { return editor.CollectionType; }
                        }
 
-                       public override ISite Site {
-                               [MonoTODO]
-                               get { throw new NotImplementedException(); } 
+                       protected ITypeDescriptorContext Context
+                       {
+                               get { return editor.Context; }
+                       }
 
-                               [MonoTODO]
-                               set { throw new NotImplementedException(); }
+                       public object EditValue
+                       {
+                               get { return editValue; }
+                               set
+                               {
+                                       editValue = value;
+                                       OnEditValueChanged ();
+                               }
                        }
 
-                       protected Type CollectionItemType {
-                               [MonoTODO]
-                               get { throw new NotImplementedException(); }
+                       protected object[] Items
+                       {
+                               get { return editor.GetItems (editValue); }
+                               set {
+                                       if (editValue == null) {
+                                               object newEmptyCollection = null;
+                                               try {
+                                                       if (typeof (Array).IsAssignableFrom (CollectionType))
+                                                               newEmptyCollection = Array.CreateInstance (CollectionItemType, 0);
+                                                       else
+                                                               newEmptyCollection = Activator.CreateInstance (CollectionType);
+                                               } catch {}
+
+                                               object val = editor.SetItems (newEmptyCollection, value);
+                                               if (val != newEmptyCollection)
+                                                       EditValue = val;
+                                       } else {
+                                               object val = editor.SetItems (editValue, value);
+                                               if (val != editValue)
+                                                       EditValue = val;
+                                       }
+                               }
                        }
-                       
-                       protected Type CollectionType {
-                               [MonoTODO]
-                               get { throw new NotImplementedException(); }
+
+                       protected Type[] NewItemTypes
+                       {
+                               get { return editor.NewItemTypes; }
                        }
 
-                       protected ITypeDescriptorContext Context {
-                               [MonoTODO]
-                               get { throw new NotImplementedException(); }
+                       protected bool CanRemoveInstance (object value)
+                       {
+                               return editor.CanRemoveInstance (value);
                        }
 
-                       protected override ImeMode DefaultImeMode {
-                               [MonoTODO]
-                               get { throw new NotImplementedException(); }
+                       protected virtual bool CanSelectMultipleInstances ()
+                       {
+                               return editor.CanSelectMultipleInstances ();
                        }
 
-                       protected object[] Items {
-                               [MonoTODO]
-                               get { throw new NotImplementedException(); } 
+                       protected object CreateInstance (Type itemType)
+                       {
+                               return editor.CreateInstance (itemType);
+                       }
 
-                               [MonoTODO]
-                               set { throw new NotImplementedException(); }
+                       protected void DestroyInstance (object instance)
+                       {
+                               editor.DestroyInstance (instance);
                        }
 
-                       protected Type[] NewItemTypes {
-                               [MonoTODO]
-                               get { throw new NotImplementedException(); }
+                       protected virtual void DisplayError (Exception e)
+                       {
+                               MessageBox.Show (e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
 
-                       [MonoTODO]
-                       protected bool CanRemoveInstance (object value)
+                       protected override object GetService (Type serviceType)
                        {
-                               throw new NotImplementedException();
+                               return editor.GetService (serviceType);
                        }
 
-                       [MonoTODO]
-                       protected virtual bool CanSelectMultipleInstances()
+                       protected abstract void OnEditValueChanged ();
+
+                       protected internal virtual DialogResult ShowEditorDialog (IWindowsFormsEditorService edSvc)
                        {
-                               throw new NotImplementedException();
+                               return edSvc.ShowDialog (this);
                        }
+               }
 
-                       [MonoTODO]
-                       protected object CreateInstance (Type itemType)
+               private class ConcreteCollectionForm : CollectionForm
+               {
+                       internal class ObjectContainerConverter : TypeConverter
                        {
-                               throw new NotImplementedException();
+                               private class ObjectContainerPropertyDescriptor : TypeConverter.SimplePropertyDescriptor
+                               {
+                                       private AttributeCollection attributes;
+
+                                       public ObjectContainerPropertyDescriptor (Type componentType, Type propertyType)
+                                               : base (componentType, "Value", propertyType)
+                                       {
+                                               CategoryAttribute cat = new CategoryAttribute (propertyType.Name);
+                                               attributes = new AttributeCollection (new Attribute[] { cat });
+                                       }
+
+                                       public override object GetValue (object component)
+                                       {
+                                               ObjectContainer container = (ObjectContainer)component;
+                                               return container.Object;
+                                       }
+
+                                       public override void SetValue (object component, object value)
+                                       {
+                                               ObjectContainer container = (ObjectContainer)component;
+                                               container.Object = value;
+                                       }
+
+                                       public override AttributeCollection Attributes
+                                       {
+                                               get { return attributes; }
+                                       }
+                               }
+
+                               public override PropertyDescriptorCollection GetProperties (ITypeDescriptorContext context, object value, Attribute[] attributes)
+                               {
+                                       ObjectContainer container = (ObjectContainer)value;
+                                       ObjectContainerPropertyDescriptor desc = new ObjectContainerPropertyDescriptor (value.GetType (), container.editor.CollectionItemType);
+                                       PropertyDescriptor[] properties = new PropertyDescriptor[] { desc };
+                                       PropertyDescriptorCollection pc = new PropertyDescriptorCollection (properties);
+                                       return pc;
+                               }
+
+                               public override bool GetPropertiesSupported (ITypeDescriptorContext context)
+                               {
+                                       return true;
+                               }
                        }
 
-                       [MonoTODO]
-                       protected void DestroyInstance (object instance)
+                       [TypeConverter (typeof (ObjectContainerConverter))]
+                       private class ObjectContainer
                        {
-                               throw new NotImplementedException();
+                               internal object Object;
+                               internal CollectionEditor editor;
+
+                               public ObjectContainer (object obj, CollectionEditor editor)
+                               {
+                                       this.Object = obj;
+                                       this.editor = editor;
+                               }
+
+                               internal string Name {
+                                       get { return editor.GetDisplayText (Object); }
+                               }
+
+                               public override string ToString ()
+                               {
+                                       return Name;
+                               }
                        }
 
-                       [MonoTODO]
-                       protected virtual void DisplayError (Exception e)
+                       private class UpdateableListbox : ListBox
                        {
-                               throw new NotImplementedException();
+                               public void DoRefreshItem (int index)
+                               {
+                                       base.RefreshItem (index);
+                               }
                        }
 
-                       [MonoTODO]
-                       protected override object GetService (Type serviceType)
+                       private CollectionEditor editor;
+
+                       private System.Windows.Forms.Label labelMember;
+                       private System.Windows.Forms.Label labelProperty;
+                       private UpdateableListbox itemsList;
+                       private System.Windows.Forms.PropertyGrid itemDisplay;
+                       private System.Windows.Forms.Button doClose;
+                       private System.Windows.Forms.Button moveUp;
+                       private System.Windows.Forms.Button moveDown;
+                       private System.Windows.Forms.Button doAdd;
+                       private System.Windows.Forms.Button doRemove;
+                       private System.Windows.Forms.Button doCancel;
+                       private System.Windows.Forms.ComboBox addType;
+
+                       public ConcreteCollectionForm (CollectionEditor editor)
+                               : base (editor)
+                       {
+                               this.editor = editor;
+
+                               this.labelMember = new System.Windows.Forms.Label ();
+                               this.labelProperty = new System.Windows.Forms.Label ();
+                               this.itemsList = new UpdateableListbox ();
+                               this.itemDisplay = new System.Windows.Forms.PropertyGrid ();
+                               this.doClose = new System.Windows.Forms.Button ();
+                               this.moveUp = new System.Windows.Forms.Button ();
+                               this.moveDown = new System.Windows.Forms.Button ();
+                               this.doAdd = new System.Windows.Forms.Button ();
+                               this.doRemove = new System.Windows.Forms.Button ();
+                               this.doCancel = new System.Windows.Forms.Button ();
+                               this.addType = new System.Windows.Forms.ComboBox ();
+                               this.SuspendLayout ();
+                               // 
+                               // labelMember
+                               // 
+                               this.labelMember.Location = new System.Drawing.Point (12, 9);
+                               this.labelMember.Size = new System.Drawing.Size (55, 13);
+                               this.labelMember.Text = "Members:";
+                               // 
+                               // labelProperty
+                               // 
+                               this.labelProperty.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                                                       | System.Windows.Forms.AnchorStyles.Right)));
+                               this.labelProperty.Location = new System.Drawing.Point (172, 9);
+                               this.labelProperty.Size = new System.Drawing.Size (347, 13);
+                               this.labelProperty.Text = "Properties:";
+                               // 
+                               // itemsList
+                               // 
+                               this.itemsList.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                                                       | System.Windows.Forms.AnchorStyles.Left)));
+                               this.itemsList.HorizontalScrollbar = true;
+                               this.itemsList.Location = new System.Drawing.Point (12, 25);
+                               this.itemsList.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
+                               this.itemsList.Size = new System.Drawing.Size (120, 290);
+                               this.itemsList.TabIndex = 0;
+                               this.itemsList.SelectedIndexChanged += new System.EventHandler (this.itemsList_SelectedIndexChanged);
+                               // 
+                               // itemDisplay
+                               // 
+                               this.itemDisplay.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                                                       | System.Windows.Forms.AnchorStyles.Left)
+                                                       | System.Windows.Forms.AnchorStyles.Right)));
+                               this.itemDisplay.HelpVisible = false;
+                               this.itemDisplay.Location = new System.Drawing.Point (175, 25);
+                               this.itemDisplay.Size = new System.Drawing.Size (344, 314);
+                               this.itemDisplay.TabIndex = 6;
+                               this.itemDisplay.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler (this.itemDisplay_PropertyValueChanged);
+                               // 
+                               // doClose
+                               // 
+                               this.doClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+                               this.doClose.Location = new System.Drawing.Point (341, 345);
+                               this.doClose.Size = new System.Drawing.Size (86, 26);
+                               this.doClose.TabIndex = 7;
+                               this.doClose.Text = "OK";
+                               this.doClose.Click += new System.EventHandler (this.doClose_Click);
+                               // 
+                               // moveUp
+                               // 
+                               this.moveUp.Location = new System.Drawing.Point (138, 25);
+                               this.moveUp.Size = new System.Drawing.Size (31, 28);
+                               this.moveUp.TabIndex = 4;
+                               this.moveUp.Enabled = false;
+                               this.moveUp.Text = "Up";
+                               this.moveUp.Click += new System.EventHandler (this.moveUp_Click);
+                               // 
+                               // moveDown
+                               // 
+                               this.moveDown.Location = new System.Drawing.Point (138, 59);
+                               this.moveDown.Size = new System.Drawing.Size (31, 28);
+                               this.moveDown.TabIndex = 5;
+                               this.moveDown.Enabled = false;
+                               this.moveDown.Text = "Dn";
+                               this.moveDown.Click += new System.EventHandler (this.moveDown_Click);
+                               // 
+                               // doAdd
+                               // 
+                               this.doAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+                               this.doAdd.Location = new System.Drawing.Point (12, 346);
+                               this.doAdd.Size = new System.Drawing.Size (59, 25);
+                               this.doAdd.TabIndex = 1;
+                               this.doAdd.Text = "Add";
+                               this.doAdd.Click += new System.EventHandler (this.doAdd_Click);
+                               // 
+                               // doRemove
+                               // 
+                               this.doRemove.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+                               this.doRemove.Location = new System.Drawing.Point (77, 346);
+                               this.doRemove.Size = new System.Drawing.Size (55, 25);
+                               this.doRemove.TabIndex = 2;
+                               this.doRemove.Text = "Remove";
+                               this.doRemove.Click += new System.EventHandler (this.doRemove_Click);
+                               // 
+                               // doCancel
+                               // 
+                               this.doCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+                               this.doCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+                               this.doCancel.Location = new System.Drawing.Point (433, 345);
+                               this.doCancel.Size = new System.Drawing.Size (86, 26);
+                               this.doCancel.TabIndex = 8;
+                               this.doCancel.Text = "Cancel";
+                               this.doCancel.Click += new System.EventHandler (this.doCancel_Click);
+                               // 
+                               // addType
+                               // 
+                               this.addType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+                               this.addType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+                               this.addType.Location = new System.Drawing.Point (12, 319);
+                               this.addType.Size = new System.Drawing.Size (120, 21);
+                               this.addType.TabIndex = 3;
+                               // 
+                               // DesignerForm
+                               // 
+                               this.AcceptButton = this.doClose;
+                               this.CancelButton = this.doCancel;
+                               this.ClientSize = new System.Drawing.Size (531, 381);
+                               this.ControlBox = false;
+                               this.Controls.Add (this.addType);
+                               this.Controls.Add (this.doCancel);
+                               this.Controls.Add (this.doRemove);
+                               this.Controls.Add (this.doAdd);
+                               this.Controls.Add (this.moveDown);
+                               this.Controls.Add (this.moveUp);
+                               this.Controls.Add (this.doClose);
+                               this.Controls.Add (this.itemDisplay);
+                               this.Controls.Add (this.itemsList);
+                               this.Controls.Add (this.labelProperty);
+                               this.Controls.Add (this.labelMember);
+                               this.HelpButton = true;
+                               this.MaximizeBox = false;
+                               this.MinimizeBox = false;
+                               this.MinimumSize = new System.Drawing.Size (400, 300);
+                               this.ShowInTaskbar = false;
+                               this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+                               this.ResumeLayout (false);
+
+                               if (editor.CollectionType.IsGenericType)
+                                       this.Text = editor.CollectionItemType.Name + " Collection Editor";
+                               else
+                                       this.Text = editor.CollectionType.Name + " Collection Editor";
+                               foreach (Type type in editor.NewItemTypes)
+                                       addType.Items.Add (type.Name);
+                               if (addType.Items.Count > 0)
+                                       addType.SelectedIndex = 0;
+                       }
+
+                       private void UpdateItems ()
+                       {
+                               object[] items = editor.GetItems (EditValue);
+                               if (items != null) {
+                                       itemsList.BeginUpdate ();
+                                       itemsList.Items.Clear ();
+                                       foreach (object o in items)
+                                               this.itemsList.Items.Add (new ObjectContainer (o, editor));
+                                       if (itemsList.Items.Count > 0)
+                                               itemsList.SelectedIndex = 0;
+                                       itemsList.EndUpdate ();
+                               }
+                       }
+
+                       private void doClose_Click (object sender, EventArgs e)
+                       {
+                               SetEditValue ();
+                               this.Close ();
+                       }
+
+                       private void SetEditValue ()
+                       {
+                               object[] items = new object[itemsList.Items.Count];
+                               for (int i = 0; i < itemsList.Items.Count; i++)
+                                       items[i] = ((ObjectContainer)itemsList.Items[i]).Object;
+                               this.Items = items;
+                       }
+
+                       private void doCancel_Click (object sender, EventArgs e)
+                       {
+                               editor.CancelChanges ();
+                               this.Close ();
+                       }
+
+                       private void itemsList_SelectedIndexChanged (object sender, EventArgs e)
                        {
-                               throw new NotImplementedException();
+                               if (itemsList.SelectedIndex == -1) {
+                                       itemDisplay.SelectedObject = null;
+                                       return;
+                               }
+
+                               if (itemsList.SelectedIndex <= 0 || itemsList.SelectedItems.Count > 1)
+                                       moveUp.Enabled = false;
+                               else
+                                       moveUp.Enabled = true;
+                               if (itemsList.SelectedIndex > itemsList.Items.Count - 2 || itemsList.SelectedItems.Count > 1)
+                                       moveDown.Enabled = false;
+                               else
+                                       moveDown.Enabled = true;
+
+                               if (itemsList.SelectedItems.Count == 1)
+                               {
+                                       ObjectContainer o = (ObjectContainer)itemsList.SelectedItem;
+                                       if (Type.GetTypeCode (o.Object.GetType ()) != TypeCode.Object)
+                                               itemDisplay.SelectedObject = o;
+                                       else
+                                               itemDisplay.SelectedObject = o.Object;
+                               }
+                               else
+                               {
+                                       object[] items = new object[itemsList.SelectedItems.Count];
+                                       for (int i = 0; i < itemsList.SelectedItems.Count; i++)
+                                       {
+                                               ObjectContainer o = (ObjectContainer)itemsList.SelectedItem;
+                                               if (Type.GetTypeCode (o.Object.GetType ()) != TypeCode.Object)
+                                                       items[i] = ((ObjectContainer)itemsList.SelectedItems[i]);
+                                               else
+                                                       items[i] = ((ObjectContainer)itemsList.SelectedItems[i]).Object;
+                                       }
+                                       itemDisplay.SelectedObjects = items;
+                               }
+                               labelProperty.Text = ((ObjectContainer)itemsList.SelectedItem).Name + " properties:";
                        }
 
-                       protected abstract void OnEditValueChanged();
+                       private void itemDisplay_PropertyValueChanged (object sender, EventArgs e)
+                       {
+                               int[] selected = new int[itemsList.SelectedItems.Count];
+                               for (int i = 0; i < itemsList.SelectedItems.Count; i++)
+                                       selected[i] = itemsList.Items.IndexOf (itemsList.SelectedItems[i]);
+
+                               // The list might be repopulated if a new instance of the collection edited
+                               // is created during the update. This happen for example for Arrays.
+                               SetEditValue ();
+
+                               // Restore current selection in case the list gets repopulated.
+                               // Refresh the item after that to reflect possible value change.
+                               // 
+                               itemsList.BeginUpdate ();
+                               itemsList.ClearSelected ();
+                               foreach (int index in selected) {
+                                       itemsList.DoRefreshItem (index);
+                                       itemsList.SetSelected (index, true);
+                               }
+                               itemsList.SelectedIndex = selected[0];
+                               itemsList.EndUpdate ();
+                       }
 
-                       [MonoTODO]
-                       protected internal virtual DialogResult ShowEditorDialog (
-                                                  IWindowsFormsEditorService edSvc)
+                       private void moveUp_Click (object sender, EventArgs e)
                        {
-                               throw new NotImplementedException();
+                               if (itemsList.SelectedIndex <= 0)
+                                       return;
+
+                               object selected = itemsList.SelectedItem;
+                               int index = itemsList.SelectedIndex;
+                               itemsList.Items.RemoveAt (index);
+                               itemsList.Items.Insert (index - 1, selected);
+                               itemsList.SelectedIndex = index - 1;
+                       }
+
+                       private void moveDown_Click (object sender, EventArgs e)
+                       {
+                               if (itemsList.SelectedIndex > itemsList.Items.Count - 2)
+                                       return;
+
+                               object selected = itemsList.SelectedItem;
+                               int index = itemsList.SelectedIndex;
+                               itemsList.Items.RemoveAt (index);
+                               itemsList.Items.Insert (index + 1, selected);
+                               itemsList.SelectedIndex = index + 1;
+                       }
+
+                       private void doAdd_Click (object sender, EventArgs e)
+                       {
+                               object o;
+                               try {
+                                       o = editor.CreateInstance (editor.NewItemTypes[addType.SelectedIndex]);
+                               } catch (Exception ex) {
+                                       DisplayError (ex);
+                                       return;
+                               }
+                               itemsList.Items.Add (new ObjectContainer (o, editor));
+                               itemsList.SelectedIndex = -1;
+                               itemsList.SelectedIndex = itemsList.Items.Count - 1;
+                       }
+
+                       private void doRemove_Click (object sender, EventArgs e)
+                       {
+                               if (itemsList.SelectedIndex != -1) {
+                                       int[] selected = new int[itemsList.SelectedItems.Count];
+                                       for (int i=0; i < itemsList.SelectedItems.Count; i++)
+                                               selected[i] = itemsList.Items.IndexOf (itemsList.SelectedItems[i]);
+
+                                       for (int i = selected.Length - 1; i >= 0; i--)
+                                               itemsList.Items.RemoveAt (selected[i]);
+
+                                       itemsList.SelectedIndex = Math.Min (selected[0], itemsList.Items.Count-1);
+                               }
                        }
 
-                       [MonoTODO]
-                       ~CollectionForm ()
+                       // OnEditValueChanged is called only if the  EditValue has changed,
+                       // which is only in the case when a new instance of the collection is 
+                       // required, e.g for arrays.
+                       // 
+                       protected override void OnEditValueChanged ()
                        {
+                               UpdateItems ();
                        }
                }
 
-               [MonoTODO]
+               private Type type;
+               private Type collectionItemType;
+               private Type[] newItemTypes;
+               private ITypeDescriptorContext context;
+               private IServiceProvider provider;
+               private IWindowsFormsEditorService editorService;
+
                public CollectionEditor (Type type)
                {
+                       this.type = type;
+                       this.collectionItemType = CreateCollectionItemType ();
+                       this.newItemTypes = CreateNewItemTypes ();
                }
 
-               [MonoTODO]
-               public override object EditValue (ITypeDescriptorContext context,
-                                                 IServiceProvider provider,
-                                                 object value)
+               protected Type CollectionItemType
                {
-                       throw new NotImplementedException();
+                       get { return collectionItemType; }
                }
 
-               [MonoTODO]
-               public override UITypeEditorEditStyle GetEditStyle (
-                                                     ITypeDescriptorContext context)
+               protected Type CollectionType
                {
-                       throw new NotImplementedException();
+                       get { return type; }
                }
 
-               protected Type CollectionItemType {
-                       [MonoTODO]
-                       get { throw new NotImplementedException(); }
+               protected ITypeDescriptorContext Context
+               {
+                       get { return context; }
                }
 
-               protected Type CollectionType {
-                       [MonoTODO]
-                       get { throw new NotImplementedException(); }
+               protected virtual string HelpTopic
+               {
+                       get { return "CollectionEditor"; }
                }
 
-               protected ITypeDescriptorContext Context {
-                       [MonoTODO]
-                       get { throw new NotImplementedException(); }
-               }
-               
-               protected virtual string HelpTopic {
-                       [MonoTODO]
-                       get { throw new NotImplementedException(); }
+               protected Type[] NewItemTypes
+               {
+                       get { return newItemTypes; }
                }
 
-               protected Type[] NewItemTypes {
-                       [MonoTODO]
-                       get { throw new NotImplementedException(); }
+               protected virtual void CancelChanges ()
+               {
                }
 
-               [MonoTODO]
                protected virtual bool CanRemoveInstance (object value)
                {
-                       throw new NotImplementedException();
+                       return true;
                }
 
-               [MonoTODO]
-               protected virtual bool CanSelectMultipleInstances()
+               protected virtual bool CanSelectMultipleInstances ()
                {
-                       throw new NotImplementedException();
+                       return true;
                }
 
-               [MonoTODO]
-               protected virtual CollectionForm CreateCollectionForm()
+               protected virtual CollectionEditor.CollectionForm CreateCollectionForm ()
                {
-                       throw new NotImplementedException();
+                       return new ConcreteCollectionForm (this);
                }
 
-               [MonoTODO]
-               protected virtual Type CreateCollectionItemType()
+               protected virtual Type CreateCollectionItemType ()
                {
-                       throw new NotImplementedException();
+                       PropertyInfo[] properties = type.GetProperties ();
+                       foreach (PropertyInfo property in properties)
+                               if (property.Name == "Item")
+                                       return property.PropertyType;
+                       return typeof (object);
                }
-
-               [MonoTODO]
+               
                protected virtual object CreateInstance (Type itemType)
                {
-                       throw new NotImplementedException();
-               }
+                       object instance = null;
+                       if (typeof (IComponent).IsAssignableFrom (itemType)) {
+                               IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+                               if (host != null)
+                                       instance = host.CreateComponent (itemType);
+                       }
 
-               [MonoTODO]
-               protected virtual Type[] CreateNewItemTypes()
+                       if (instance == null) {
+                               instance = TypeDescriptor.CreateInstance (provider, itemType, null, null);
+                       }
+                       return instance;
+               }
+               
+               protected virtual Type[] CreateNewItemTypes ()
                {
-                       throw new NotImplementedException();
+                       return new Type[] { collectionItemType };
                }
 
-               [MonoTODO]
                protected virtual void DestroyInstance (object instance)
                {
-                       throw new NotImplementedException();
+                       IComponent component = instance as IComponent;
+                       if (component != null) {
+                               IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+                               if (host != null)
+                                       host.DestroyComponent (component);
+                       }
+               }
+
+               public override object EditValue (ITypeDescriptorContext context, IServiceProvider provider, object value)
+               {
+                       this.context = context;
+                       this.provider = provider;
+
+                       if (context != null && provider != null)
+                       {
+                               editorService = (IWindowsFormsEditorService)provider.GetService (typeof (IWindowsFormsEditorService));
+                               if (editorService != null)
+                               {
+                                       CollectionForm editorForm = CreateCollectionForm ();
+                                       editorForm.EditValue = value;
+                                       editorForm.ShowEditorDialog (editorService);
+                                       return editorForm.EditValue;
+                               }
+                       }
+                       return base.EditValue (context, provider, value);
+               }
+
+               protected virtual string GetDisplayText (object value)
+               {
+                       if (value == null)
+                               return string.Empty;
+
+                       PropertyInfo nameProperty = value.GetType ().GetProperty ("Name");
+                       if (nameProperty != null)
+                       {
+                               string data = (nameProperty.GetValue (value, null)) as string;
+                               if (data != null)
+                                       if (data.Length != 0)
+                                               return data;
+                       }
+
+                       if (Type.GetTypeCode (value.GetType ()) == TypeCode.Object)
+                               return value.GetType ().Name;
+                       else
+                               return value.ToString ();
+               }
+
+               public override UITypeEditorEditStyle GetEditStyle (ITypeDescriptorContext context)
+               {
+                       return UITypeEditorEditStyle.Modal;
                }
 
-               [MonoTODO]
                protected virtual object[] GetItems (object editValue)
                {
-                       throw new NotImplementedException();
+                       if (editValue == null)
+                               return new object[0];
+                       ICollection collection = editValue as ICollection;
+                       if (collection == null)
+                               return new object[0];
+
+                       object[] result = new object[collection.Count];
+                       collection.CopyTo (result, 0);
+                       return result;
+               }
+
+               protected virtual IList GetObjectsFromInstance (object instance)
+               {
+                       ArrayList list = new ArrayList ();
+                       list.Add (instance);
+                       return list;
                }
 
-               [MonoTODO]
                protected object GetService (Type serviceType)
                {
-                       throw new NotImplementedException();
+                       return context.GetService (serviceType);
                }
 
-               [MonoTODO]
-               protected virtual object SetItems (object editValue,
-                                                  object[] value)
+               protected virtual object SetItems (object editValue, object[] value)
                {
-                       throw new NotImplementedException();
+                       IList list = (IList) editValue;
+                       if (list == null)
+                               return null;
+
+                       list.Clear ();
+                       foreach (object o in value)
+                               list.Add (o);
+
+                       return list;
                }
 
-               [MonoTODO]
-               protected virtual void ShowHelp()
+               protected virtual void ShowHelp ()
                {
-                       throw new NotImplementedException();
+                       //TODO: Fixme Add parent and URL
+                       Help.ShowHelp (null, "", HelpTopic);
                }
        }
 }