* CollectionEditor.cs: Implement CreateInstance for 1.1 profile (patch
[mono.git] / mcs / class / System.Design / System.ComponentModel.Design / CollectionEditor.cs
1 //
2 // System.ComponentModel.Design.CollectionEditor
3 //
4 // Authors:
5 //      Martin Willemoes Hansen (mwh@sysrq.dk)
6 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 // 
8 // (C) 2003 Martin Willemoes Hansen
9 // (C) 2007 Andreas Nahr
10 //
11
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33
34 using System;
35 using System.Reflection;
36 using System.Collections;
37 using System.ComponentModel;
38 using System.Drawing.Design;
39 using System.Windows.Forms;
40 using System.Windows.Forms.Design;
41
42 namespace System.ComponentModel.Design
43 {
44         public class CollectionEditor : UITypeEditor
45         {
46                 protected abstract class CollectionForm : Form
47                 {
48                         private CollectionEditor editor;
49                         private object editValue;
50
51                         public CollectionForm (CollectionEditor editor)
52                         {
53                                 this.editor = editor;
54                         }
55
56                         protected Type CollectionItemType
57                         {
58                                 get { return editor.CollectionItemType; }
59                         }
60
61                         protected Type CollectionType
62                         {
63                                 get { return editor.CollectionType; }
64                         }
65
66                         protected ITypeDescriptorContext Context
67                         {
68                                 get { return editor.Context; }
69                         }
70
71                         public object EditValue
72                         {
73                                 get { return editValue; }
74                                 set
75                                 {
76                                         editValue = value;
77                                         OnEditValueChanged ();
78                                 }
79                         }
80
81                         protected object[] Items
82                         {
83                                 get { return editor.GetItems (editValue); }
84                                 set { editor.SetItems (editValue, value); }
85                         }
86
87                         protected Type[] NewItemTypes
88                         {
89                                 get { return editor.NewItemTypes; }
90                         }
91
92                         protected bool CanRemoveInstance (object value)
93                         {
94                                 return editor.CanRemoveInstance (value);
95                         }
96
97                         protected virtual bool CanSelectMultipleInstances ()
98                         {
99                                 return editor.CanSelectMultipleInstances ();
100                         }
101
102                         protected object CreateInstance (Type itemType)
103                         {
104                                 return editor.CreateInstance (itemType);
105                         }
106
107                         protected void DestroyInstance (object instance)
108                         {
109                                 editor.DestroyInstance (instance);
110                         }
111
112                         protected virtual void DisplayError (Exception e)
113                         {
114                                 MessageBox.Show (e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
115                         }
116
117                         protected override object GetService (Type serviceType)
118                         {
119                                 return editor.GetService (serviceType);
120                         }
121
122                         protected abstract void OnEditValueChanged ();
123
124                         protected internal virtual DialogResult ShowEditorDialog (IWindowsFormsEditorService edSvc)
125                         {
126                                 return edSvc.ShowDialog (this);
127                         }
128                 }
129
130                 private class ConcreteCollectionForm : CollectionForm
131                 {
132                         internal class ObjectContainerConverter : TypeConverter
133                         {
134                                 private class ObjectContainerPropertyDescriptor : TypeConverter.SimplePropertyDescriptor
135                                 {
136                                         private AttributeCollection attributes;
137
138                                         public ObjectContainerPropertyDescriptor (Type componentType, Type propertyType)
139                                                 : base (componentType, "Value", propertyType)
140                                         {
141                                                 CategoryAttribute cat = new CategoryAttribute (propertyType.Name);
142                                                 attributes = new AttributeCollection (new Attribute[] { cat });
143                                         }
144
145                                         public override object GetValue (object component)
146                                         {
147                                                 ObjectContainer container = (ObjectContainer)component;
148                                                 return container.Object;
149                                         }
150
151                                         public override void SetValue (object component, object value)
152                                         {
153                                                 ObjectContainer container = (ObjectContainer)component;
154                                                 container.Object = value;
155                                         }
156
157                                         public override AttributeCollection Attributes
158                                         {
159                                                 get { return attributes; }
160                                         }
161                                 }
162
163                                 public override PropertyDescriptorCollection GetProperties (ITypeDescriptorContext context, object value, Attribute[] attributes)
164                                 {
165                                         ObjectContainer container = (ObjectContainer)value;
166                                         ObjectContainerPropertyDescriptor desc = new ObjectContainerPropertyDescriptor (value.GetType (), container.editor.CollectionItemType);
167                                         PropertyDescriptor[] properties = new PropertyDescriptor[] { desc };
168                                         PropertyDescriptorCollection pc = new PropertyDescriptorCollection (properties);
169                                         return pc;
170                                 }
171
172                                 public override bool GetPropertiesSupported (ITypeDescriptorContext context)
173                                 {
174                                         return true;
175                                 }
176                         }
177
178                         [TypeConverter (typeof (ObjectContainerConverter))]
179                         private class ObjectContainer
180                         {
181                                 internal string Name;
182                                 internal object Object;
183                                 internal CollectionEditor editor;
184
185                                 public ObjectContainer (string name, object obj, CollectionEditor editor)
186                                 {
187                                         this.Name = name;
188                                         this.Object = obj;
189                                         this.editor = editor;
190                                 }
191
192                                 public override string ToString ()
193                                 {
194                                         return Name;
195                                 }
196                         }
197
198                         private class UpdateableListbox : ListBox
199                         {
200                                 public void DoRefreshItem (int index)
201                                 {
202                                         base.RefreshItem (index);
203                                 }
204                         }
205
206                         private CollectionEditor editor;
207
208                         private System.Windows.Forms.Label labelMember;
209                         private System.Windows.Forms.Label labelProperty;
210                         private UpdateableListbox itemsList;
211                         private System.Windows.Forms.PropertyGrid itemDisplay;
212                         private System.Windows.Forms.Button doClose;
213                         private System.Windows.Forms.Button moveUp;
214                         private System.Windows.Forms.Button moveDown;
215                         private System.Windows.Forms.Button doAdd;
216                         private System.Windows.Forms.Button doRemove;
217                         private System.Windows.Forms.Button doCancel;
218                         private System.Windows.Forms.ComboBox addType;
219
220                         public ConcreteCollectionForm (CollectionEditor editor)
221                                 : base (editor)
222                         {
223                                 this.editor = editor;
224
225                                 this.labelMember = new System.Windows.Forms.Label ();
226                                 this.labelProperty = new System.Windows.Forms.Label ();
227                                 this.itemsList = new UpdateableListbox ();
228                                 this.itemDisplay = new System.Windows.Forms.PropertyGrid ();
229                                 this.doClose = new System.Windows.Forms.Button ();
230                                 this.moveUp = new System.Windows.Forms.Button ();
231                                 this.moveDown = new System.Windows.Forms.Button ();
232                                 this.doAdd = new System.Windows.Forms.Button ();
233                                 this.doRemove = new System.Windows.Forms.Button ();
234                                 this.doCancel = new System.Windows.Forms.Button ();
235                                 this.addType = new System.Windows.Forms.ComboBox ();
236                                 this.SuspendLayout ();
237                                 // 
238                                 // labelMember
239                                 // 
240                                 this.labelMember.Location = new System.Drawing.Point (12, 9);
241                                 this.labelMember.Size = new System.Drawing.Size (55, 13);
242                                 this.labelMember.Text = "Members:";
243                                 // 
244                                 // labelProperty
245                                 // 
246                                 this.labelProperty.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
247                                                         | System.Windows.Forms.AnchorStyles.Right)));
248                                 this.labelProperty.Location = new System.Drawing.Point (172, 9);
249                                 this.labelProperty.Size = new System.Drawing.Size (347, 13);
250                                 this.labelProperty.Text = "Properties:";
251                                 // 
252                                 // itemsList
253                                 // 
254                                 this.itemsList.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
255                                                         | System.Windows.Forms.AnchorStyles.Left)));
256                                 this.itemsList.HorizontalScrollbar = true;
257                                 this.itemsList.Location = new System.Drawing.Point (12, 25);
258                                 this.itemsList.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
259                                 this.itemsList.Size = new System.Drawing.Size (120, 290);
260                                 this.itemsList.TabIndex = 0;
261                                 this.itemsList.SelectedIndexChanged += new System.EventHandler (this.itemsList_SelectedIndexChanged);
262                                 // 
263                                 // itemDisplay
264                                 // 
265                                 this.itemDisplay.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
266                                                         | System.Windows.Forms.AnchorStyles.Left)
267                                                         | System.Windows.Forms.AnchorStyles.Right)));
268                                 this.itemDisplay.HelpVisible = false;
269                                 this.itemDisplay.Location = new System.Drawing.Point (175, 25);
270                                 this.itemDisplay.Size = new System.Drawing.Size (344, 314);
271                                 this.itemDisplay.TabIndex = 6;
272                                 this.itemDisplay.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler (this.itemDisplay_PropertyValueChanged);
273                                 // 
274                                 // doClose
275                                 // 
276                                 this.doClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
277                                 this.doClose.Location = new System.Drawing.Point (341, 345);
278                                 this.doClose.Size = new System.Drawing.Size (86, 26);
279                                 this.doClose.TabIndex = 7;
280                                 this.doClose.Text = "OK";
281                                 this.doClose.Click += new System.EventHandler (this.doClose_Click);
282                                 // 
283                                 // moveUp
284                                 // 
285                                 this.moveUp.Location = new System.Drawing.Point (138, 25);
286                                 this.moveUp.Size = new System.Drawing.Size (31, 28);
287                                 this.moveUp.TabIndex = 4;
288                                 this.moveUp.Text = "Up";
289                                 this.moveUp.Click += new System.EventHandler (this.moveUp_Click);
290                                 // 
291                                 // moveDown
292                                 // 
293                                 this.moveDown.Location = new System.Drawing.Point (138, 59);
294                                 this.moveDown.Size = new System.Drawing.Size (31, 28);
295                                 this.moveDown.TabIndex = 5;
296                                 this.moveDown.Text = "Dn";
297                                 this.moveDown.Click += new System.EventHandler (this.moveDown_Click);
298                                 // 
299                                 // doAdd
300                                 // 
301                                 this.doAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
302                                 this.doAdd.Location = new System.Drawing.Point (12, 346);
303                                 this.doAdd.Size = new System.Drawing.Size (59, 25);
304                                 this.doAdd.TabIndex = 1;
305                                 this.doAdd.Text = "Add";
306                                 this.doAdd.Click += new System.EventHandler (this.doAdd_Click);
307                                 // 
308                                 // doRemove
309                                 // 
310                                 this.doRemove.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
311                                 this.doRemove.Location = new System.Drawing.Point (77, 346);
312                                 this.doRemove.Size = new System.Drawing.Size (55, 25);
313                                 this.doRemove.TabIndex = 2;
314                                 this.doRemove.Text = "Remove";
315                                 this.doRemove.Click += new System.EventHandler (this.doRemove_Click);
316                                 // 
317                                 // doCancel
318                                 // 
319                                 this.doCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
320                                 this.doCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
321                                 this.doCancel.Location = new System.Drawing.Point (433, 345);
322                                 this.doCancel.Size = new System.Drawing.Size (86, 26);
323                                 this.doCancel.TabIndex = 8;
324                                 this.doCancel.Text = "Cancel";
325                                 this.doCancel.Click += new System.EventHandler (this.doCancel_Click);
326                                 // 
327                                 // addType
328                                 // 
329                                 this.addType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
330                                 this.addType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
331                                 this.addType.Location = new System.Drawing.Point (12, 319);
332                                 this.addType.Size = new System.Drawing.Size (120, 21);
333                                 this.addType.TabIndex = 3;
334                                 // 
335                                 // DesignerForm
336                                 // 
337                                 this.AcceptButton = this.doClose;
338                                 this.CancelButton = this.doCancel;
339                                 this.ClientSize = new System.Drawing.Size (531, 381);
340                                 this.ControlBox = false;
341                                 this.Controls.Add (this.addType);
342                                 this.Controls.Add (this.doCancel);
343                                 this.Controls.Add (this.doRemove);
344                                 this.Controls.Add (this.doAdd);
345                                 this.Controls.Add (this.moveDown);
346                                 this.Controls.Add (this.moveUp);
347                                 this.Controls.Add (this.doClose);
348                                 this.Controls.Add (this.itemDisplay);
349                                 this.Controls.Add (this.itemsList);
350                                 this.Controls.Add (this.labelProperty);
351                                 this.Controls.Add (this.labelMember);
352                                 this.HelpButton = true;
353                                 this.MaximizeBox = false;
354                                 this.MinimizeBox = false;
355                                 this.MinimumSize = new System.Drawing.Size (400, 300);
356                                 this.ShowInTaskbar = false;
357                                 this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
358                                 this.ResumeLayout (false);
359
360 #if NET_2_0
361                                 if (editor.CollectionType.IsGenericType)
362                                         this.Text = editor.CollectionItemType.Name + " Collection Editor";
363                                 else
364                                         this.Text = editor.CollectionType.Name + " Collection Editor";
365 #else
366                                 this.Text = editor.CollectionType.Name + " Collection Editor";
367 #endif
368                                 foreach (Type type in editor.NewItemTypes)
369                                         addType.Items.Add (type.Name);
370                                 if (addType.Items.Count > 0)
371                                         addType.SelectedIndex = 0;
372                         }
373
374                         private void AddItems ()
375                         {
376                                 foreach (object o in editor.GetItems (EditValue))
377                                 {
378                                         this.itemsList.Items.Add (new ObjectContainer (editor.GetDisplayText (o), o, editor));
379                                 }
380                                 if (itemsList.Items.Count > 0)
381                                         itemsList.SelectedIndex = 0;
382                         }
383
384                         private void doClose_Click (object sender, EventArgs e)
385                         {
386                                 object[] items = new object[itemsList.Items.Count];
387                                 for (int i = 0; i < itemsList.Items.Count; i++)
388                                         items[i] = ((ObjectContainer)itemsList.Items[i]).Object;
389                                 EditValue = editor.SetItems (EditValue, items);
390                                 this.Close ();
391                         }
392
393                         private void doCancel_Click (object sender, EventArgs e)
394                         {
395                                 editor.CancelChanges ();
396                                 this.Close ();
397                         }
398
399                         private void itemsList_SelectedIndexChanged (object sender, EventArgs e)
400                         {
401                                 if (itemsList.SelectedIndex <= 0 || itemsList.SelectedItems.Count > 1)
402                                         moveUp.Enabled = false;
403                                 else
404                                         moveUp.Enabled = true;
405                                 if (itemsList.SelectedIndex > itemsList.Items.Count - 2 || itemsList.SelectedItems.Count > 1)
406                                         moveDown.Enabled = false;
407                                 else
408                                         moveDown.Enabled = true;
409
410                                 if (itemsList.SelectedIndex == -1)
411                                         return;
412
413                                 if (itemsList.SelectedItems.Count == 1)
414                                 {
415                                         ObjectContainer o = (ObjectContainer)itemsList.SelectedItem;
416                                         if (Type.GetTypeCode (o.Object.GetType ()) != TypeCode.Object)
417                                                 itemDisplay.SelectedObject = o;
418                                         else
419                                                 itemDisplay.SelectedObject = o.Object;
420                                 }
421                                 else
422                                 {
423                                         object[] items = new object[itemsList.SelectedItems.Count];
424                                         for (int i = 0; i < itemsList.SelectedItems.Count; i++)
425                                         {
426                                                 ObjectContainer o = (ObjectContainer)itemsList.SelectedItem;
427                                                 if (Type.GetTypeCode (o.Object.GetType ()) != TypeCode.Object)
428                                                         items[i] = ((ObjectContainer)itemsList.SelectedItems[i]);
429                                                 else
430                                                         items[i] = ((ObjectContainer)itemsList.SelectedItems[i]).Object;
431                                         }
432                                         itemDisplay.SelectedObjects = items;
433                                 }
434                                 labelProperty.Text = ((ObjectContainer)itemsList.SelectedItem).Name + " properties:";
435                         }
436
437                         private void itemDisplay_PropertyValueChanged (object sender, EventArgs e)
438                         {
439                                 int[] indices = new int[itemsList.SelectedIndices.Count];
440                                 itemsList.SelectedIndices.CopyTo (indices, 0);
441                                 for (int i = 0; i < indices.Length; i++)
442                                 {
443                                         ObjectContainer o = (ObjectContainer)itemsList.Items [indices[i]];
444                                         o.Name = editor.GetDisplayText (o.Object);
445                                         itemsList.DoRefreshItem (indices[i]);
446                                 }
447                                 for (int i = 0; i < indices.Length; i++)
448                                         itemsList.SetSelected (indices[i], true);
449                         }
450
451                         private void moveUp_Click (object sender, EventArgs e)
452                         {
453                                 if (itemsList.SelectedIndex <= 0)
454                                         return;
455
456                                 object selected = itemsList.SelectedItem;
457                                 int index = itemsList.SelectedIndex;
458                                 itemsList.Items.RemoveAt (index);
459                                 itemsList.Items.Insert (index - 1, selected);
460                                 itemsList.SelectedIndex = index - 1;
461                         }
462
463                         private void moveDown_Click (object sender, EventArgs e)
464                         {
465                                 if (itemsList.SelectedIndex > itemsList.Items.Count - 2)
466                                         return;
467
468                                 object selected = itemsList.SelectedItem;
469                                 int index = itemsList.SelectedIndex;
470                                 itemsList.Items.RemoveAt (index);
471                                 itemsList.Items.Insert (index + 1, selected);
472                                 itemsList.SelectedIndex = index + 1;
473                         }
474
475                         private void doAdd_Click (object sender, EventArgs e)
476                         {
477                                 object o;
478                                 try
479                                 {
480                                         o = editor.CreateInstance (editor.NewItemTypes[addType.SelectedIndex]);
481                                 }
482                                 catch (Exception ex)
483                                 {
484                                         DisplayError (ex);
485                                         return;
486                                 }
487                                 itemsList.Items.Add (new ObjectContainer (editor.GetDisplayText (o), o, editor));
488                         }
489
490                         private void doRemove_Click (object sender, EventArgs e)
491                         {
492                                 if (itemsList.SelectedIndex != -1)
493                                         itemsList.Items.RemoveAt (itemsList.SelectedIndex);
494                         }
495
496                         protected override void OnEditValueChanged ()
497                         {
498                                 AddItems ();
499                         }
500                 }
501
502                 private Type type;
503                 private Type collectionItemType;
504                 private Type[] newItemTypes;
505                 private ITypeDescriptorContext context;
506                 private IServiceProvider provider;
507                 private IWindowsFormsEditorService editorService;
508
509                 public CollectionEditor (Type type)
510                 {
511                         this.type = type;
512                         this.collectionItemType = CreateCollectionItemType ();
513                         this.newItemTypes = CreateNewItemTypes ();
514                 }
515
516                 protected Type CollectionItemType
517                 {
518                         get { return collectionItemType; }
519                 }
520
521                 protected Type CollectionType
522                 {
523                         get { return type; }
524                 }
525
526                 protected ITypeDescriptorContext Context
527                 {
528                         get { return context; }
529                 }
530
531                 protected virtual string HelpTopic
532                 {
533                         get { return "CollectionEditor"; }
534                 }
535
536                 protected Type[] NewItemTypes
537                 {
538                         get { return newItemTypes; }
539                 }
540
541                 protected virtual void CancelChanges ()
542                 {
543                 }
544
545                 protected virtual bool CanRemoveInstance (object value)
546                 {
547                         return true;
548                 }
549
550                 protected virtual bool CanSelectMultipleInstances ()
551                 {
552                         return true;
553                 }
554
555                 protected virtual CollectionEditor.CollectionForm CreateCollectionForm ()
556                 {
557                         return new ConcreteCollectionForm (this);
558                 }
559
560                 protected virtual Type CreateCollectionItemType ()
561                 {
562                         PropertyInfo info = type.GetProperty ("Item");
563                         return info.PropertyType;
564                 }
565                 
566                 protected virtual object CreateInstance (Type itemType)
567                 {
568 #if NET_2_0
569                         return TypeDescriptor.CreateInstance (provider, itemType, null, null);
570 #else
571                         return Activator.CreateInstance (itemType);
572 #endif
573                 }
574                 
575                 protected virtual Type[] CreateNewItemTypes ()
576                 {
577                         return new Type[] { collectionItemType };
578                 }
579
580                 protected virtual void DestroyInstance (object instance)
581                 {
582                         //FIXME: I've got NO clue what this does and the documentation isn't helpfull either
583                 }
584
585                 public override object EditValue (ITypeDescriptorContext context, IServiceProvider provider, object value)
586                 {
587                         this.context = context;
588                         this.provider = provider;
589
590                         if (context != null && provider != null)
591                         {
592                                 editorService = (IWindowsFormsEditorService)provider.GetService (typeof (IWindowsFormsEditorService));
593                                 if (editorService != null)
594                                 {
595                                         CollectionForm editorForm = CreateCollectionForm ();
596                                         editorForm.EditValue = value;
597
598                                         editorForm.ShowEditorDialog (editorService);
599
600                                         return editorForm.EditValue;
601                                 }
602                         }
603                         return base.EditValue (context, provider, value);
604                 }
605
606                 protected virtual string GetDisplayText (object value)
607                 {
608                         if (value == null)
609                                 return string.Empty;
610
611                         PropertyInfo nameProperty = value.GetType ().GetProperty ("Name");
612                         if (nameProperty != null)
613                         {
614                                 string data = (nameProperty.GetValue (value, null)) as string;
615                                 if (data != null)
616                                         if (data.Length != 0)
617                                                 return data;
618                         }
619
620                         if (Type.GetTypeCode (value.GetType ()) == TypeCode.Object)
621                                 return value.GetType ().Name;
622                         else
623                                 return value.ToString ();
624                 }
625
626                 public override UITypeEditorEditStyle GetEditStyle (ITypeDescriptorContext context)
627                 {
628                         return UITypeEditorEditStyle.Modal;
629                 }
630
631                 protected virtual object[] GetItems (object editValue)
632                 {
633                         if (editValue == null)
634                                 return null;
635                         ICollection collection = editValue as ICollection;
636                         if (collection == null)
637                                 return new object[0];
638
639                         object[] result = new object[collection.Count];
640                         collection.CopyTo (result, 0);
641                         return result;
642                 }
643
644                 protected virtual IList GetObjectsFromInstance (object instance)
645                 {
646                         ArrayList list = new ArrayList ();
647                         list.Add (instance);
648                         return list;
649                 }
650
651                 protected object GetService (Type serviceType)
652                 {
653                         return context.GetService (serviceType);
654                 }
655
656                 protected virtual object SetItems (object editValue, object[] value)
657                 {
658                         IList list;
659
660                         if (editValue == null)
661                                 return null;
662
663                         if (!(editValue is IList))
664                                 list = new ArrayList ();
665                         else
666                         {
667                                 list = editValue as IList;
668                                 list.Clear ();
669                         }
670
671                         foreach (object o in value)
672                                 list.Add (o);
673
674                         return list;
675                 }
676
677                 protected virtual void ShowHelp ()
678                 {
679                         //TODO: Fixme Add parent and URL
680                         Help.ShowHelp (null, "", HelpTopic);
681                 }
682         }
683 }