This project has moved. For the latest updates, please go here.

PropertyGrid for objects in linked projects

Mar 3, 2013 at 9:34 PM
Hi there,

I've been trying to get a PropertyGrid to allow editing of an object from a library (a game engine) in an application, without specifying anything UI specific in the library project.

I've hit a bit of a brick wall, so I thought I'd ask here and see if this is possible to do at runtime.

So I have an object in my library with an integer property (using a custom attribute so I can find it while looping through the object's properties), an ID :
class Object
{
 [IdAttribute]
 public int ID
 {
  get;
  set;
 }
}
Then in my application I'm adding an ICustomTypeDescriptor to the PropertyGrid at runtime. The custom type descriptor loops through all of the properties of the Object instance it houses (myObject), and creates a custom property descriptor for each one it finds :
public PropertyDescriptorCollection GetProperties( Attribute[] attributes )  
{
 PropertyDescriptorCollection propertyCollection = new PropertyDescriptorCollection(null, false);

 // Get the properties
 if( myObject != null )
 {
    // Add the properties for the object
    PropertyInfo[] propertyInfo = myObject.GetType().GetProperties();
    foreach( PropertyInfo property in propertyInfo )
    {
      if( property.Name == "ID" )
      {
        propertyCollection.Add( new EngineObjectPropertyDescriptor(myObject, property.Name) );
      }
 }

return propertyCollection;
}
For the supplied property, the custom PropertyDescriptor returns a String displayed in the value portion of the PropertyGrid:

Image

Now the issue - I am unable to edit the value of the string at all (despite have an overridden 'set' method in my PropertyDescriptor), I can't click on it to modify the value at all. The type being returned by the PropertyDescriptor for both the Property and the Component is String.

I would also like to be able to set up a custom editor, so that a string is displayed for the IDs value (currently working), but when you click on the string value it launches a new dialogue that allows you to change the value. I've got a stand alone dialogue set up which I can easily modify, but can't figure out how to programmatically trigger it (or even edit the value of the property).

Any suggestions would be greatly appreciated!
Mar 3, 2013 at 9:52 PM
Ah I think I see what I've been doing wrong... Looks like I've been using the PropertyGrid like an old Windows.Forms property grid, instead of trying trying to use PropertyDefinitions and the ITypeEditor interface.

Is it possible to supply editors for a property at runtime instead of in the property declaration? I don't want to have to do something like :
[Editor(typeof(LastNameUserControlEditor), typeof(LastNameUserControlEditor))]
Since that would mean bringing UI code in to the library I'm linking in.
Mar 4, 2013 at 12:20 PM
Use the PropertyGrid.EditorDefinitions property.
Add an EditorDefinition, set the property name on the "Name" property.
You will have to add a template in it. See examples in the Sample App.
Mar 4, 2013 at 7:29 PM
Thanks for the advice!
Mar 5, 2013 at 8:50 AM
Edited Mar 5, 2013 at 9:04 AM
Hi there,

I'm still having a couple of issues editing all of the object properties. I've been able to set up the PropertyGrid so that most of the properties work well :

Image

But my object also contains a dictionary of other objects, indexed by Type. I'd like to add a separate Category attribute for each of the values in the dictionary, but haven't figured out exactly how to do that yet. Do I need to build a custom editor and tie it to the property that returns the dictionary?

I've tried creating an ICustomTypeDescriptor and PropertyDescriptor for the object - it loops through all the regular properties of the object, then all the properties of the values held in the dictionary - but despite the PropertyDescriptor returning the name that's associated with the EditorPropertiesDefinition, the Name property remains read-only (the PropertyDescriptor explicitly sets IsReadOnly to false) :

Image

So it's getting the Name value without any issues, I just can't set it. I have the following editor definition :
<xctk:PropertyGrid.EditorDefinitions>
 <xctk:EditorDefinition>
  <xctk:EditorDefinition.PropertiesDefinitions>
    <xctk:PropertyDefinition Name="Name" />
  </xctk:EditorDefinition.PropertiesDefinitions>
  <xctk:EditorDefinition.EditorTemplate>
   <DataTemplate>
    <TextBlock Text="{Binding Value}" />
   </DataTemplate>
  </xctk:EditorDefinition.EditorTemplate>
 </xctk:EditorDefinition>
</xctk:PropertyGrid.EditorDefinitions>
Any suggestions on what I can do, while still keeping UI specifics out of the linked project?
Mar 5, 2013 at 1:05 PM
Edited Mar 5, 2013 at 1:06 PM
Ah I think I've found out the problem - nothing to do with the setup for my PropertyDescriptors, PropertyGrid or ICustomTypeDescriptor...

I had an GetFocus event on the tab with the property grid, it was triggering every time I click the mouse and that was re-setting the SelectedObject on the PropertyGrid :)