Creating DesignerVerbs for a Reflection.Emit-ed class for use in a PropertyGrid

L

Lee Henson

Hi,

I've hit a bit of a brick wall in my use of the PropertyGrid control.
I am writing a Windows Forms application that does the following:

- dynamically create a class using Reflection.Emit - the class simply
holds a number of properties ("Name", "Description", etc).
- pass the class to a PropertyGrid control which then renders the
properties for the user to edit.

This is all working fine, and I have even added my own Category and
Description attributes to the properties which are showing up
successfully in the PropertyGrid. My problem is that I would also like
to add a couple of DesignerVerbs to the class, so that I can offer
"Add Property" and "Remove Property" functions in the PropertyGrid. I
have set the CommandsVisibleIfAvailable flag on my PropertyGrid, and
attempted to set the Designer attribute on my dynamically-created
class. The Designer attribute points to a custom ComponentDesigner
class, in which I have defined the DesignerVerbs. However, the verbs
are not being shown in the PropertyGrid.

I may have a lead in that the Attributes property of my TypeBuilder
class still says "NotPublic" after I SetCustomAttribute. But does that
mean the contents of the Attributes collection are not public, or that
my class' only attribute is "NotPublic"?

Any ideas on something I might have missed? Below is some example
code, in the hope that it jogs someone's memory! I'd be happy to post
anything else that may be relevant.

Cheers
Lee

**********************************************
*** snippet from DynamicCmSchemaCreator.cs ***
*** creates the DesignerAttribute using my ***
*** custom ComponentDesigner class ***

TypeBuilder typeBuilder = moduleBuilder.DefineType
(
DynamicType,
TypeAttributes.Class,
typeof(Component)
);

// Apply the Designer attribute, supplying our own ComponentDesign
class

CustomAttributeBuilder customAttributeBuilder = new
CustomAttributeBuilder
(
typeof(DesignerAttribute).GetConstructor(new Type[] { typeof(Type)
}),
new object[] { typeof(DynamicCmSchemaComponentDesigner) }
);

typeBuilder.SetCustomAttribute(customAttributeBuilder);

*******************************************
*** DynamicCmSchemaComponentDesigner.cs ***
*** the componentdesigner I attach to ***
*** the dynamic class ***

public class DynamicCmSchemaComponentDesigner : ComponentDesigner
{
private const string AddPropertyVerb = "Add Property";
private const string RemovePropertyVerb = "Remove Property";

private DesignerVerbCollection verbs;

private void OnAddPropertyVerb(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Processing Add Property");
}

private void OnRemovePropertyVerb(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Processing Remove
Property");
}

public override DesignerVerbCollection Verbs
{
get
{
if (verbs == null)
{
verbs = new DesignerVerbCollection();
verbs.Add(new DesignerVerb(AddPropertyVerb, new
EventHandler(OnAddPropertyVerb)));
verbs.Add(new DesignerVerb(RemovePropertyVerb, new
EventHandler(OnRemovePropertyVerb)));
}

return verbs;
}
}
}

****************************************
*** snippet from MainForm.cs ***
*** creates the dynamic class and ***
*** passes it to the propertygrid ***

object dynamicCmSchema = DynamicCmSchemaCreator.CreateDynamicCmSchema
(
node.CmSchema.Properties
);

this.propertyGrid.SelectedObject = dynamicCmSchema;

*******************************************
 
S

Sean Hederman

I tried to do something similar a while back. It appears that the
PropertyGrid only displays the Verbs when hosted in VS and displaying a
Component. I never was able to find out how to get this working in my own
app.

Lee Henson said:
Hi,

I've hit a bit of a brick wall in my use of the PropertyGrid control.
I am writing a Windows Forms application that does the following:

- dynamically create a class using Reflection.Emit - the class simply
holds a number of properties ("Name", "Description", etc).
- pass the class to a PropertyGrid control which then renders the
properties for the user to edit.

This is all working fine, and I have even added my own Category and
Description attributes to the properties which are showing up
successfully in the PropertyGrid. My problem is that I would also like
to add a couple of DesignerVerbs to the class, so that I can offer
"Add Property" and "Remove Property" functions in the PropertyGrid. I
have set the CommandsVisibleIfAvailable flag on my PropertyGrid, and
attempted to set the Designer attribute on my dynamically-created
class. The Designer attribute points to a custom ComponentDesigner
class, in which I have defined the DesignerVerbs. However, the verbs
are not being shown in the PropertyGrid.

I may have a lead in that the Attributes property of my TypeBuilder
class still says "NotPublic" after I SetCustomAttribute. But does that
mean the contents of the Attributes collection are not public, or that
my class' only attribute is "NotPublic"?

Any ideas on something I might have missed? Below is some example
code, in the hope that it jogs someone's memory! I'd be happy to post
anything else that may be relevant.

Cheers
Lee

**********************************************
*** snippet from DynamicCmSchemaCreator.cs ***
*** creates the DesignerAttribute using my ***
*** custom ComponentDesigner class ***

TypeBuilder typeBuilder = moduleBuilder.DefineType
(
DynamicType,
TypeAttributes.Class,
typeof(Component)
);

// Apply the Designer attribute, supplying our own ComponentDesign
class

CustomAttributeBuilder customAttributeBuilder = new
CustomAttributeBuilder
(
typeof(DesignerAttribute).GetConstructor(new Type[] { typeof(Type)
}),
new object[] { typeof(DynamicCmSchemaComponentDesigner) }
);

typeBuilder.SetCustomAttribute(customAttributeBuilder);

*******************************************
*** DynamicCmSchemaComponentDesigner.cs ***
*** the componentdesigner I attach to ***
*** the dynamic class ***

public class DynamicCmSchemaComponentDesigner : ComponentDesigner
{
private const string AddPropertyVerb = "Add Property";
private const string RemovePropertyVerb = "Remove Property";

private DesignerVerbCollection verbs;

private void OnAddPropertyVerb(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Processing Add Property");
}

private void OnRemovePropertyVerb(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Processing Remove
Property");
}

public override DesignerVerbCollection Verbs
{
get
{
if (verbs == null)
{
verbs = new DesignerVerbCollection();
verbs.Add(new DesignerVerb(AddPropertyVerb, new
EventHandler(OnAddPropertyVerb)));
verbs.Add(new DesignerVerb(RemovePropertyVerb, new
EventHandler(OnRemovePropertyVerb)));
}

return verbs;
}
}
}

****************************************
*** snippet from MainForm.cs ***
*** creates the dynamic class and ***
*** passes it to the propertygrid ***

object dynamicCmSchema = DynamicCmSchemaCreator.CreateDynamicCmSchema
(
node.CmSchema.Properties
);

this.propertyGrid.SelectedObject = dynamicCmSchema;

*******************************************
 
L

Lee Henson

Thanks Sean. I got the feeling it was a design-time feature. I guess
I'll just have to drop this idea.
 
S

Sean Hederman

Lee Henson said:
Thanks Sean. I got the feeling it was a design-time feature. I guess
I'll just have to drop this idea.

It *should* be possible, I just never found out how.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top