3c1f479b9d
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
740 lines
22 KiB
C#
740 lines
22 KiB
C#
//
|
|
// System.ComponentModel.Design.CollectionEditor
|
|
//
|
|
// 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
|
|
//
|
|
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// 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
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// 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;
|
|
|
|
namespace System.ComponentModel.Design
|
|
{
|
|
public class CollectionEditor : UITypeEditor
|
|
{
|
|
protected abstract class CollectionForm : Form
|
|
{
|
|
private CollectionEditor editor;
|
|
private object editValue;
|
|
|
|
public CollectionForm (CollectionEditor editor)
|
|
{
|
|
this.editor = editor;
|
|
}
|
|
|
|
protected Type CollectionItemType
|
|
{
|
|
get { return editor.CollectionItemType; }
|
|
}
|
|
|
|
protected Type CollectionType
|
|
{
|
|
get { return editor.CollectionType; }
|
|
}
|
|
|
|
protected ITypeDescriptorContext Context
|
|
{
|
|
get { return editor.Context; }
|
|
}
|
|
|
|
public object EditValue
|
|
{
|
|
get { return editValue; }
|
|
set
|
|
{
|
|
editValue = value;
|
|
OnEditValueChanged ();
|
|
}
|
|
}
|
|
|
|
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[] NewItemTypes
|
|
{
|
|
get { return editor.NewItemTypes; }
|
|
}
|
|
|
|
protected bool CanRemoveInstance (object value)
|
|
{
|
|
return editor.CanRemoveInstance (value);
|
|
}
|
|
|
|
protected virtual bool CanSelectMultipleInstances ()
|
|
{
|
|
return editor.CanSelectMultipleInstances ();
|
|
}
|
|
|
|
protected object CreateInstance (Type itemType)
|
|
{
|
|
return editor.CreateInstance (itemType);
|
|
}
|
|
|
|
protected void DestroyInstance (object instance)
|
|
{
|
|
editor.DestroyInstance (instance);
|
|
}
|
|
|
|
protected virtual void DisplayError (Exception e)
|
|
{
|
|
MessageBox.Show (e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
}
|
|
|
|
protected override object GetService (Type serviceType)
|
|
{
|
|
return editor.GetService (serviceType);
|
|
}
|
|
|
|
protected abstract void OnEditValueChanged ();
|
|
|
|
protected internal virtual DialogResult ShowEditorDialog (IWindowsFormsEditorService edSvc)
|
|
{
|
|
return edSvc.ShowDialog (this);
|
|
}
|
|
}
|
|
|
|
private class ConcreteCollectionForm : CollectionForm
|
|
{
|
|
internal class ObjectContainerConverter : TypeConverter
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
[TypeConverter (typeof (ObjectContainerConverter))]
|
|
private class ObjectContainer
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
private class UpdateableListbox : ListBox
|
|
{
|
|
public void DoRefreshItem (int index)
|
|
{
|
|
base.RefreshItem (index);
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
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:";
|
|
}
|
|
|
|
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 ();
|
|
}
|
|
|
|
private void moveUp_Click (object sender, EventArgs e)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
|
|
// 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 ();
|
|
}
|
|
}
|
|
|
|
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 ();
|
|
}
|
|
|
|
protected Type CollectionItemType
|
|
{
|
|
get { return collectionItemType; }
|
|
}
|
|
|
|
protected Type CollectionType
|
|
{
|
|
get { return type; }
|
|
}
|
|
|
|
protected ITypeDescriptorContext Context
|
|
{
|
|
get { return context; }
|
|
}
|
|
|
|
protected virtual string HelpTopic
|
|
{
|
|
get { return "CollectionEditor"; }
|
|
}
|
|
|
|
protected Type[] NewItemTypes
|
|
{
|
|
get { return newItemTypes; }
|
|
}
|
|
|
|
protected virtual void CancelChanges ()
|
|
{
|
|
}
|
|
|
|
protected virtual bool CanRemoveInstance (object value)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
protected virtual bool CanSelectMultipleInstances ()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
protected virtual CollectionEditor.CollectionForm CreateCollectionForm ()
|
|
{
|
|
return new ConcreteCollectionForm (this);
|
|
}
|
|
|
|
protected virtual Type CreateCollectionItemType ()
|
|
{
|
|
PropertyInfo[] properties = type.GetProperties ();
|
|
foreach (PropertyInfo property in properties)
|
|
if (property.Name == "Item")
|
|
return property.PropertyType;
|
|
return typeof (object);
|
|
}
|
|
|
|
protected virtual object CreateInstance (Type itemType)
|
|
{
|
|
object instance = null;
|
|
if (typeof (IComponent).IsAssignableFrom (itemType)) {
|
|
IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
|
|
if (host != null)
|
|
instance = host.CreateComponent (itemType);
|
|
}
|
|
|
|
if (instance == null) {
|
|
instance = TypeDescriptor.CreateInstance (provider, itemType, null, null);
|
|
}
|
|
return instance;
|
|
}
|
|
|
|
protected virtual Type[] CreateNewItemTypes ()
|
|
{
|
|
return new Type[] { collectionItemType };
|
|
}
|
|
|
|
protected virtual void DestroyInstance (object instance)
|
|
{
|
|
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;
|
|
}
|
|
|
|
protected virtual object[] GetItems (object editValue)
|
|
{
|
|
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;
|
|
}
|
|
|
|
protected object GetService (Type serviceType)
|
|
{
|
|
return context.GetService (serviceType);
|
|
}
|
|
|
|
protected virtual object SetItems (object editValue, object[] value)
|
|
{
|
|
IList list = (IList) editValue;
|
|
if (list == null)
|
|
return null;
|
|
|
|
list.Clear ();
|
|
foreach (object o in value)
|
|
list.Add (o);
|
|
|
|
return list;
|
|
}
|
|
|
|
protected virtual void ShowHelp ()
|
|
{
|
|
//TODO: Fixme Add parent and URL
|
|
Help.ShowHelp (null, "", HelpTopic);
|
|
}
|
|
}
|
|
}
|