I need to initialize any new objects created with CollectionEditor with a specific reference.
More specifically, I have an object, Pipeline, that can be edited in the PropertyGrid. This object contains a collection of Markers. Markers need a reference to Pipeline in order to do some calculations.
Currently, the PropertyGrid for Pipeline has an entry for Markers. Clicking on the ellipse button brings up the CollectionEditor. Editing properties is fine, but I need to also set the current Pipeline for any new Markers created. I'm not sure of the best way to do that. Are there events I can monitor? Do I need to create a custom CollectionEditor (but how would it know anything about a specific Pipeline?)?
You need to create a custom CollectionEditor and also a custom PropertyDescriptor class. Your PropertyDescriptor can store a PipeLine object that gets passed to your collection editor by overriding PropertyDescriptor.GetEditor. You could let the PipeLine create new Markers objects and do any required initialization.
Here is some code to get you started:
public class MyCollectionEditor : System.ComponentModel.Design.CollectionEditor
{
private Pipeline _pipeline;
public MyCollectionEditor(Type type) : base(type) {}
public MyCollectionEditor(Type type, Pipeline pipeline) : base(type)
{
_pipeline = pipeline;
}
protected override object CreateInstance(Type itemType)
{
return _pipeline.CreateNewMarker();
}
}
public class MyPropertyDescriptor : PropertyDescriptor
{
private PipeLine _pipeline;
public MyPropertyDescriptor(PipeLine pipeline) : base(name, null)
{
_pipeline = pipeline;
}
public override object GetEditor(Type editorBaseType)
{
return new MyCollectionEditor(typeof(MarkerCollection), _pipeline);
}
// ... other overrides ...
}
// ...
// Implement System.ComponentModel.ICustomTypeDescriptor.GetProperties
public System.ComponentModel.PropertyDescriptorCollection GetProperties()
{
PropertyDescriptorCollection pdc = new PropertyDescriptorCollection(null);
foreach (Marker m in Markers) {
MyPropertyDescriptor pd = new MyPropertyDescriptor(m);
pdc.Add(pd);
}
return pdc;
}