Jump to content

  • Log In with Google      Sign In   
  • Create Account


C# Custom Property Editor


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 Orangeatang   Members   -  Reputation: 1435

Like
0Likes
Like

Posted 03 March 2013 - 12:54 PM

Hey folks,

 

I'm having trouble setting up (at runtime) a custom property editor for an object in my game's engine...

 

So say I have an engine object with a texture ID attribute, and to modify that ID I want to pop up a texture browser. I can't specify the editor to use for the attribute in the engine object source file, as I don't want there to be any UI stuff in my engine project, but I have added a custom attribute:

 

class Object
{
 [TextureIDAttribute]
 public int TextureID
 {
   get;
   set;
 }
}

 

In my editor I've created an ICustomTypeDescriptor for my engine objects :

 

class EngineObjectDescriptor : ICustomTypeDescriptor
{
 ...

 private Object myEngineObject;
}

 

And the GetProperties() method loops through all of the Object's properties, adding an instance of my custom PropertyDescriptor (ObjectPropertyDescriptor) for each one.

 

The trouble is no matter what I return from the overridden ComponentType & PropertyType accessors in the PropertyDescriptor, the GetEditor() function (which I assume is used to display a custom editor for the property) is never called (it isn't called in the ObjectPropertyDescriptor class either) - the ID of the object is always displayed as a non-editable integer.

 

I can change PropretyType to int32, and then I get a little value scroll thing, but what I really want is to have a button displayed that launches a texture browser and then sets the ID that way :

 

9uEfBeO.png

 

I've checked that the IsReadOnly attribute of the PropertyDescriptor is set to false, so not sure what's going on.

 

Any advice would be greatly appreciated :)



Sponsor:

#2 Orangeatang   Members   -  Reputation: 1435

Like
0Likes
Like

Posted 03 March 2013 - 01:20 PM

Come to think of it I don't really need to display a button - the name of the texture should be enough. I just need to launch my custom editor when the user clicks on the value to change it.



#3 mariofan99934   Members   -  Reputation: 113

Like
1Likes
Like

Posted 03 March 2013 - 02:04 PM

use Reflection.
I've implemented some static class variables trying to do this kind of thing before. But I wanted something cleaner.

AngelXNA has its own way of modifying instance variables at runtime (using Forms), incorporating it into serialization too I think. But it's too complex for my liking.

I've got a simple system (looks messy) for generic properties at static time and runtime, I don't know if it's complete enough yet and there are small issues with using templated types as properties. And I can't use int because I get exceptions when the compiler assumes it can convert to/from float but actually can't.


Well basically what you want to do is enumerate Type. "public MemberInfo[] GetMembers();"
and then specify a set of explicit get/set methods in your own code dealing with the Form once you have the class's editable members.

One concern though is manually putting in the values. There are other ways of input- you might consider sliders or, in Skyrim there's this pie/circle thing that you drag in a circle to change the values with more granular control over it.



#4 Orangeatang   Members   -  Reputation: 1435

Like
0Likes
Like

Posted 03 March 2013 - 02:22 PM

I've got all of the properties for the engine's Object class registered using reflection :
 

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) );
     }
}

 

So at runtime the Object (myObject) get's it's ID member added to the PropertyGrid. I'm just testing this out on a single class member, so I can get the process down.

 

I've got Get/Set methods in the EngineObjectPropertyDescriptor, but they're just operating on the basic object type... is this where I need to trigger my custom property editor (in this case the Texture Browser)? It seems like the Set method would only get called once a value has been entered in to the text box for the string property (assuming I use a string to display to the user). At the moment Set is only getting called if I set the PropertyType to int32.


Edited by Orangeatang, 03 March 2013 - 02:29 PM.


#5 Orangeatang   Members   -  Reputation: 1435

Like
0Likes
Like

Posted 03 March 2013 - 03:05 PM

Well basically what you want to do is enumerate Type. "public MemberInfo[] GetMembers();"
and then specify a set of explicit get/set methods in your own code dealing with the Form once you have the class's editable members.

I'm not sure if I can do that using a PropertyGrid - I could populate a grid layout with each member instead, but I'd prefer to use a propertygrid so I've got all of the search functionality, and collapsing items etc.

 

It seems like a property grid should work, but it's just a bit of a pain to set up.



#6 Flimflam   Members   -  Reputation: 657

Like
0Likes
Like

Posted 05 March 2013 - 04:56 PM

I'm not sure if you can have custom UITypeEditors for individual properties... I'm fairly certain it's tied almost entirely to the actual type of the property. So if "ID" is of type Int32, you'll get the standard text input box. 






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS