I haven't settled on a "definite" name yet, but I think I'm calling it "Shiny.Design" for one of my favorite adjectives from the Firefly universe. And with that in mind, let me announce my new PropertyGrid control and design project.
Current supported features include:
- Support for renaming class properties
- Designation of custom names for enumeration fields
- A replacement UI type editor for enumerations marked with the [Flags] attribute
- Support of localization by overriding a property of the new [Name] attribute.
- Support for multiple property tabs (such as an Events tab)
The above sample was generated from the following class:
1: public class TestDesignObject
2: {
3: [Name("Simple Property Example")]
4: [Browsable(true)]
5: [Category("Examples")]
6: [Description("This is just an example of giving a simple property an arbitrary name..")]
7: public string TestProp1
8: {
9: get; set;
10: }
11:
12: private string m_wow;
13: [Name("Wow, this works!")]
14: [Browsable(true)]
15: [Category("Examples")]
16: [Description("This is just an example of how a property can have a name that is apparently anything arbitrary.")]
17: public string TestProp2
18: {
19: get { return m_wow; }
20: set { m_wow = value; }
21: }
22:
23: // [Tab("Client Behavior")]
24: [Name("Battle.net Client Type")]
25: [Browsable(true)]
26: [DefaultValue(ClientType.STAR)]
27: [Category("Client Behavior")]
28: [Description("Sets the client to emulate.")]
29: public ClientType TestProp3
30: {
31: get; set;
32: }
33:
34: // [Tab("Client Behavior")]
35: [Name("Security Options")]
36: [Browsable(true)]
37: [DefaultValue(SecuritySettings.LeetSpeak | SecuritySettings.QuickLeave)]
38: [Category("Client Behavior")]
39: [Description("Sets automatic ban options.")]
40: public SecuritySettings TestProp4
41: {
42: get; set;
43: }
44: }
There were a couple enumerations, too:
1: [Flags]
2: public enum SecuritySettings
3: {
4: [Name("No Autoban")]
5: None = 0,
6: [Name("Autoban: Rapid Chat")]
7: RapidChat = 1,
8: [Name("Autoban: Rapid Join/Leave")]
9: QuickLeave = 2,
10: [Name("Autoban: L33t Sp34K")]
11: LeetSpeak = 4,
12: }
13: public enum ClientType
14: {
15: [Name("Starcraft (Retail)")]
16: STAR,
17: [Name("Starcraft: Brood War")]
18: SEXP,
19: [Name("Diablo II (Retail)")]
20: D2DV,
21: [Name("Diablo II: The Lord of Destruction")]
22: D2XP,
23: [Name("Japan Starcraft")]
24: JSTR,
25: [Name("Warcraft II: Battle.net Edition")]
26: W2BN,
27: [Name("Warcraft III: The Reign of Chaos")]
28: WAR3,
29: [Name("Warcraft III: The Frozen Throne")]
30: W3XP,
31: }
These enumeration types are derived from a personal project for a Battle.net client. ;-)
In any case, the setup is pretty helpful. It's based on a project originally written by Tony Allowatt posted on CodeProject. I've used the PropertyBag class for a long time now, and in a more recent project I augmented it into an "AutoPropertyBag" class with a similar design. My new design library uses original code, though, and it explicitly uses a design pattern. The class that does all the magic in this library is called "TypeDescriptorSurrogate" and provides all of the benefits of the library (with the exception of multiple PropertyTabs) by wrapping the object being examined. It implements ICustomTypeDescriptor and exports PropertyDescriptor objects as necessary.
Anyway - stay tuned for a download link in the coming week!