Context
I have a very large number of small classes or structures. The implementation details of these classes are not important, but for each of these there will be a few simple built-in data type properties that I want to expose so that they can be edited in a WinForms control. These will be completely different from class to class though. For example:
class SleepAction : IGameAction
{
public float Duration { get; set; }
}
class TeleportCharacterAction : IGameAction
{
public string CharacterId { get; set;
public string DestinationRoomId { get; set; }
public Vector2 DestinationPosition { get; set; }
}
The problem is that I wanted to have a single WinForms control that is capable of editing all of these object types. There would be a dropdown list of all the class types on top, and when selecting an item from this dropdown list, the interface would change to accomodate the properties of that type, as well as create an instance of that type to store the data.
At first I was considering handcrafting each of these interfaces, possibly using a TabControl object, one tab per class, with the tabs hidden. But then the number of classes grew exponentially, so I'm turning to some other solution, probably using attributes and reflection. I'm just not sure how to get started.
What I have in mind now is something like:
class ActionEditorControl : UserControl
{
void ChangeEditorMode(Type type)
{
// Clear all GUI interface
// Create object of type Type with default constructor
// Use Type metadata to generate new GUI interface
// Databind new interface to object properties
}
object GetObject()
{
// Return current object
}
}
And on my model objects I could use attributes to add the necessary metadata:
class SleepAction : IGameAction
{
[FieldLabel("Duration")]
[FieldType("NumericSpinner")]
public float Duration { get; set; }
}
class TeleportCharacterAction : IGameAction
{
[FieldLabel("Character")]
[FieldType("CharacterList")]
public string CharacterId { get; set;
[FieldLabel("Room")]
[FieldType("RoomList")]
public string DestinationRoomId { get; set; }
[FieldLabel("Position")]
[FieldType("VectorPicker")]
public Vector2 DestinationPosition { get; set; }
}
Of course I'd need to teach my control how to interpret these attributes. Now for my actual questions.
Specific Questions
- Would this work?
- Is there a better alternative to solving this problem that I'm overlooking?
- How to deal with the placement or layout of the controls in the interface?
- Finally, I've never used custom attributes before. Any good example to get me started?