I am creating a List<> of a Test class, I made. I then convert it to an array and assign it to a propertygrid control.
List<Test> lc_Test;
public class Test : UserControl
{
[Category("lc_Test"), Description("Testing using List<>, for storage."), DisplayName("Images")]
public Image img { get; set; }
}
// Above in Form1(), I create it
// lc_Test = new List<Test>();
private void button7_Click(object sender, EventArgs e)
{
lc_Test.Clear();
lc_Test.Add(new Test());
lc_Test.Add(new Test());
lc_Test[0].img = pb1.Image;
lc_Test[1].img = pb2.Image;
MessageBox.Show(lc_Test.Count.ToString());
pgTest.SelectedObject = lc_Test.ToArray();
}
As seen in the picture, it works:
I am now wondering, if there is any way to change the Display Name of each item. Cause, it names them "(0)" and "(1)". In this test, I'd like to change it to say. "Test Item 0" and "Test Item 1". I need to change the "Help Text" for each item, also. Got to be a way.
Anyone, need anything from me let me know.
Solution:
Your form1.cs code file:
using System;
using System.Windows.Forms;
namespace PropertyGridSample
{
public class Form1 : System.Windows.Forms.Form
{
Layers layers_test;
internal System.Windows.Forms.PropertyGrid PropertyGrid1;
private System.ComponentModel.Container components = null; //Required designer variable
public Form1()
{
InitializeComponent();
layers_test = new Layers();
PropertyGrid1.SelectedObject = layers_test;
}
// Clean up any resources being used
protected override void Dispose( bool disposing )
{
if (disposing) { if (components != null) { components.Dispose(); } }
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.PropertyGrid1 = new System.Windows.Forms.PropertyGrid();
this.SuspendLayout();
//
// PropertyGrid1
//
this.PropertyGrid1.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.PropertyGrid1.LineColor = System.Drawing.SystemColors.ScrollBar;
this.PropertyGrid1.Location = new System.Drawing.Point(0, -1);
this.PropertyGrid1.Name = "PropertyGrid1";
this.PropertyGrid1.PropertySort = System.Windows.Forms.PropertySort.Alphabetical;
this.PropertyGrid1.Size = new System.Drawing.Size(408, 254);
this.PropertyGrid1.TabIndex = 1;
this.PropertyGrid1.ToolbarVisible = false;
this.PropertyGrid1.SelectedGridItemChanged += new System.Windows.Forms.SelectedGridItemChangedEventHandler(this.PropertyGrid1_SelectedGridItemChanged);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(408, 254);
this.Controls.Add(this.PropertyGrid1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.Name = "Form1";
this.Text = "Customizing Collections in Property Grid Demo";
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void PropertyGrid1_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
{
PropertyGrid1.Refresh();
}
}
}
I made a separate cs file, called LayerCollection.cs:
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
namespace PropertyGridSample
{
[TypeConverter(typeof(LayerConverter))]
public class Layer
{
public Image image { get; set; }
public Layer() { }
}
public class Layers
{
LayerCollection layercollection = new LayerCollection();
public Layers()
{
Layer[] layz = new Layer[2];
Layer lay1 = new Layer(); Layer lay2 = new Layer(); //Create two test layers and add them to the layer collection
layercollection.Add(lay1); layercollection.Add(lay2);
}
[TypeConverter(typeof(LayerCollectionConverter))]
public LayerCollection Layer_Collection { get { return layercollection; } }
}
public class LayerCollection : CollectionBase, ICustomTypeDescriptor
{
#region collection impl
public void Add(Layer lay) { List.Add(lay); } //Adds a layer object to the collection
public void Remove(Layer lay) { List.Remove(lay); } //Removes a layer object from the collection
public Layer this[int index] { get { return (List.Count > -1 && index < List.Count) ? (Layer)List[index] : null; } } //Return a layer object at index position
#endregion
#region ICustomTypeDescriptor impl
public AttributeCollection GetAttributes() { return TypeDescriptor.GetAttributes(this, true); }
public String GetClassName() { return TypeDescriptor.GetClassName(this, true); }
public String GetComponentName() { return TypeDescriptor.GetComponentName(this, true); }
public TypeConverter GetConverter() { return TypeDescriptor.GetConverter(this, true); }
public EventDescriptor GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); }
public PropertyDescriptor GetDefaultProperty() { return TypeDescriptor.GetDefaultProperty(this, true); }
public EventDescriptorCollection GetEvents(Attribute[] attributes) { return TypeDescriptor.GetEvents(this, attributes, true); }
public EventDescriptorCollection GetEvents() { return TypeDescriptor.GetEvents(this, true); }
public object GetEditor(Type editorBaseType) { return TypeDescriptor.GetEditor(this, editorBaseType, true); }
public object GetPropertyOwner(PropertyDescriptor pd) { return this; }
//Called to get the properties of this type. Returns properties with certain attributes. this restriction is not implemented here.
public PropertyDescriptorCollection GetProperties(Attribute[] attributes) { return GetProperties(); }
//Called to get the properties of this type.
public PropertyDescriptorCollection GetProperties()
{
PropertyDescriptorCollection pds = new PropertyDescriptorCollection(null); // Create a collection object to hold property descriptors
// Iterate the list of layers and create a property descriptor for each layer item and add to the property descriptor collection
for (int i = 0; i < this.List.Count; i++) { LayerCollectionPropertyDescriptor pd = new LayerCollectionPropertyDescriptor(this, i); pds.Add(pd); }
return pds; // return the descriptor collection
}
#endregion
}
class LayerConverter : ExpandableObjectConverter
{
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destType)
{
return (destType == typeof(string) && value is Layer) ? "Layer Data": base.ConvertTo(context, culture, value, destType);
}
}
class LayerCollectionConverter : ExpandableObjectConverter
{
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destType)
{
return (destType == typeof(string) && value is LayerCollection) ? "Items": base.ConvertTo(context, culture, value, destType);
}
}
public class LayerCollectionPropertyDescriptor : PropertyDescriptor
{
private LayerCollection collection = null;
private int index = -1;
public LayerCollectionPropertyDescriptor(LayerCollection coll, int idx) : base("#" + idx.ToString(), null)
{
collection = coll; index = idx;
}
public override AttributeCollection Attributes { get { return new AttributeCollection(null); } }
public override bool CanResetValue(object component) { return true; }
public override bool IsReadOnly { get { return false; } }
public override bool ShouldSerializeValue(object component) { return true; }
public override string Description { get { return "Layer Description"; } }
public override string DisplayName { get { return "Layer " + index.ToString(); } }
public override string Name { get { return "#" + index.ToString(); } }
public override object GetValue(object component) { return collection[index]; }
public override Type ComponentType { get { return collection.GetType(); } }
public override Type PropertyType { get { return collection[index].GetType(); } }
public override void ResetValue(object component) { }
public override void SetValue(object component, object value) { } // this.collection[index] = value;
}
}
On your form, you just need to throw a propertygrid on it. I'm still looking at ways to improve it and need the ability to trap the add and remove buttons, on the built in collection editor