Thursday, March 5, 2009

Design-Time Properties

Ever wanted to have a Designer-Only properties, whose only purpose is to do something in Visual Studio? I guess you already almost know how to do this. Simply create a property with Getters / Setters and assign an Editor to it, but there are a few things you can do to enhance it.

Let’s say we want to create a property that will be shown on PropertyEditor and assign it an editor so that when the editor is activated we get an About dialog about our control / component. Fancy enough?

so let’s create our basic property. After thinking about it, we don’t need a setter at all and since this is a design time property the return value and return type are also unimportant. So we’re down to this:

public object About
{
get { return null; }
}

Assigning an property Editor is relatively easy. Create a new class and inherit from UITypeEditor override a couple of methods and you’re all set:

[EditorBrowsable(EditorBrowsableState.Never)]
internal sealed class AboutDialogEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}

public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
About about = new About();
about.ShowDialog();
about.Dispose();

return null;
}
}

What we’re doing here is first to specify our editor should be opened in Modal mode, and second when the value is requested for that property (Editor is invoked), we just display our about dialog. So, by assigning this editor to our property, it should work:

[Editor(typeof(AboutDialogEditor), typeof(UITypeEditor))]
public object About
{
get { return null; }
}

AboutDialog-FirstTake

There are some other things to do. First, our property is displayed “somewhere” in the PropertyEditor. That’s not what we want for an About dialog, is it? We need the property to appear always first and we need to somehow distinct it from other normal properties. What we can do about it is to use ParenthesizePropertyNameAttribute which simply signifies what our property should be treated specially, just like the standard Name property which is displayed above the others and is in parentheses. Also, to explicitly declare that our property is only a design-time property we’ll add a DesignOnlyAttribute:

[DesignOnly(true)]
[ParenthesizePropertyName(true)]
[Editor(typeof(AboutDialogEditor), typeof(UITypeEditor))]
public object About
{
get { return null; }
}

The only thing left here is that we don’t want developers working with our controls see this property, because of the fact that it is a design-time property. To do this we add a EditorBrowsableAttribute and make our property Hidden in the texteditor of Visual Studio. So here’s how our final property looks like:

[DesignOnly(true)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[ParenthesizePropertyName(true)]
[Editor(typeof(AboutDialogEditor), typeof(UITypeEditor))]
public object About
{
get { return null; }
}

AboutDialog-SecondTake


Submit this story to DotNetKicks Shout it

No comments: