2009-08-12

Creating design-time compatible properties and events, part 1

We all create custom or user controls and classes all day and, of course, custom properties and events. Well, whenever you create you own control, it’s properties are automatically show in the property window at design time. But our properties don’t look the same as the built in ones for objects, right? Those have got categories, descriptions, lists with custom values, and so on. And for custom events, they don’t even show up!

In this two part article, I’ll be showing you how to make your properties and events more “developer friendly” (nice term, right?). In part 1, I’ll be talking about simple properties, and in part 2 we’ll get to events and custom lists.

This is what any built in property for, let’s say, a TextBox looks like:

 

We got:

  1. A category
  2. A custom list, which provides from an enumeration
  3. A description of what the property does

We can get that for our properties and events as well, so first, to continue with the example, let’s create or custom TextBox, which will basically be a class that inherits from the TextBox class, and add a couple of properties:

  1: public partial class NiceTextBox : TextBox
  2: {
  3:     public string SomeString { get; set; }
  4: 
  5:     public int SomeInt { get; set; }
  6: }

Nice. Compile and add a NiceTextBox control to the form. Our two very clever properties will show in the Properties Window, but they’ll be under the “Misc” category (meaning they don’t have a category at all), and they will have no comment:

  

In order to make our properties “look” that way, we need to use a concept called Attributes. Attributes provide a powerful method of associating declarative information with C# code (types, methods, properties, and so forth). In our case, these attributes will “kinda” represent the metadata used by the designer in the properties window.

So, to create a category for our couple of properties, will use the “Category” attribute, like this:

  1: [Category("Custom properties")]
  2: public string SomeString { get; set; }
  3: 
  4: [Category("Custom properties")]
  5: public int SomeInt { get; set; }

Here’s what we’ll get:

Of course, the category name, which is the one in double quotes, can be anything, and it doesn’t have to be the same for all properties.

Just as the Category attribute, we can get a lot of things by using more of them, here’s a few:

  • DefaultValue – Value to set for the property by default
  • Description – Description of what he property does
  • ReadOnly – Indicates if the property can be changed at design time in the properties window. It can still be changed via code though. By default, this attribute is false.
  • DisplayName – The name to show in the properties window
  • Browsable – Indicates if the property should be shown at all at design time in the properties window. When set to false, it won’t be visible, although you can still access it at runtime, in your code. By default, this attribute is true, except for events, which is by default false.

So, let’s elaborate our properties a bit more:

  1: [Category("Custom properties"), Description("Some string used")]
  2: public string SomeString { get; set; }
  3: 
  4: [Category("Custom properties")]
  5: [Description("Some number used in the NiceTextBox")]
  6: [ReadOnly(true)]
  7: [DisplayName("SomeNumber")]
  8: public int SomeInt { get; set; }

Notice that, in the first property, SomeString, we set all attributes in the same line, separating them by commas, and in the second property, SomeInt, we did it in different lines. Both approaches are valid. So, this is what we get:

As put in our attributes, we included a description for both properties. In addition, SomeInt property will be read-only at design time, and will be shown as SomeNumber.

Of course, there are a lot more attributes than the ones I listed, but I hope you get the general idea. In part 2 of this article, I’ll be showing you some more advanced features. See you then.

No hay comentarios:

Publicar un comentario

Your tips and thoughts are always welcome, and they provide good motivation: