Categories
Design Time Support Uncategorized

Custom Controls Design Time Support Part 2: More Design Time Attributes

In my previous post I pointed out the most common used Attributes for Design Time Support. In this part I will point out some more Attributes that take advantage of the Design Time Environment.

Attributes Applied To Description
DisplayName Properties & Events Specifies the display name for a property or an event.
ParenthesizeProperty Properties  Indicates whether the name of the associated property is displayed with parentheses in the Properties window.
RefreshProperties Properties Indicates that the property grid should refresh when the associated property value changes.
NotifyParentProperty Properties Indicates that the parent property is notified when the value of the property that this attribute is applied to is modified.
ReadOnly Properties Specifies whether the property this attribute is bound to is read-only or read/write.
DesignOnly Properties

Specifies whether a property can only be set at design time.

[more] 

» DisplayNameAttribute is useful when you need the name displayed in the PropertyWindow different than property actual name.

[code:c#]

[DisplayName("Number of Clicks")]
public int NumOfClicks

[/code]

DisplayNameAttribute 

» ParenthesizePropertyAttribute when you have a special property such as Name and need it to appear between brackets this is the attribute to use.

[code:c#]

[ParenthesizePropertyName(true)]
public string SpecialProperty

[/code]

» RefreshPropertiesAttribute when you have property's value which depends on the value of another one then you will need this attribute, mark the property that when changed should refresh others with this attribute.

[code:c#]

[RefreshProperties(RefreshProperties.All)]
public string RefreshOtherProperty

[/code]

» NotifyParentPropertyAttribute Apply this one to a property if its parent property should receive notification of changes to the property's values. For example, the Size property has two nested properties: height and width. These nested properties should be marked with NotifyParentPropertyAttribute(true) so they notify the parent property to update its value and display when the property values change.

[code:c#]

[NotifyParentProperty(true)]
public string NotifyparentProperty

[/code]

» ReadOnlyAttribute When applying this attribute with parameter true then it will be unchangable in the design time, this is different than making a property without a set accessor since properties marked with ReadOnlyAttribute can be changed using code.

[code:c#]

[ReadOnly(true)]
public string ReadOnlyProperty

[/code]

» DesignOnlyAttribute from the name implies that the property marked with this attribute will only be available in the design mode.

[code:c#]

[DesignOnly(true)]
public string DesignTimeOnlyProperty

[/code]

ButtonEx.cs (3.36 kb)

Categories
Design Time Support Uncategorized

Custom Controls Design Time Support Part 1: Design Time Attributes

As I mentioned in my previous post, I am willing to write a multi part tutorial on how to add Design Time Support to your custom controls.

In this part, I will talk about the common attributes for Properties and Events

Attribute Applied To Description
Browsable Properties and events Specifies whether a property or an event should be displayed in the property browser.
Category

Properties and events

Specifies the name of the category in which to group a property or event. When categories are used, component properties and events can be displayed in logical groupings in the property browser.
Description Properties and events Defines a small block of text to be displayed at the bottom of the property browser when the user selects a property or event.
DefaultProperty Properties
(Insert this attribute before the class declaration.)
Specifies the default property for the component. This property is selected in the property browser when a user clicks on the control.
DefaultValue Properties Sets a simple default value for a property.
DefaultEvent Events
(Insert this attribute before the class declaration.)
Specifies the default event for the component. This is the event that is selected in the property browser when a user clicks on the component.

To illustrate how these attributes work I need first to set a custom control, let's start with simple windows forms button. [more]

[code:c#]

using System;
using System.Windows.Forms;

namespace Elsehemy.Controls
{
  public class ButtonEx : Button
  {
  
  }
}

[/code]

Now add a property to make use of some attributes (I will use simple ones first)

[code:c#]

private int _numOfClicks;

public int NumOfClicks
{
  get { return _numOfClicks; }
  set { _numOfClicks = value; }
}

[/code]

Now add the ButtonEx control to a windows form to test the effect of attributes one by one.

[code:c#]

[Description("Tells how many time the button has been clicked")]
public int NumOfClicks{…}

[/code]

DescriptionAttribute

[code:c#]

[Category("Special Properties")]
[Description("Tells how many time the button has been clicked")]
public int NumOfClicks{…}

[/code]

[code:c#]

[DefaultValue(10)]
[Category("Special Properties")]
[Description("Tells how many time the button has been clicked")]
public int NumOfClicks{…}

[/code]

As you can notice the default value attribute now enabled the Reset context menu item which (of course) will reset the Property value to 10, the Reset command is only enabled when the value is not equal to 10, further more the value is always bold when it is not the default.

NOTE: The DefaultValue Attribute just writes the value of the box beside the property name to the value chosen, which means the actual inner variable isn't set to that value, so if you reset the value and 10 is written then ran the program and tested for NumOfClicks value you will find it equal to 0, even though its written 10.

Solution: Make sure to set the default value in the constructor of the control to have it work as expected.

More on DefaultValue Attribute as you already noticed the constructor has overloads for different types however all types are simple (bool, int, short, string ….) and one more constructor overload that has 2 parameters a type and a string value, consider we have a System.Drawing.Color Property that needs to have a default value.

[code:c#]

[DefaultValue(typeof(System.Drawing.Color),"Red")]
public System.Drawing.Color ColorProperty

[/code]

More over not only KnownColors can be set as default values, you can set the default value as RGB by supplying its Hex value..

[code:c#]

[DefaultValue(typeof(System.Drawing.Color),"#FFBA00")]
public System.Drawing.Color ColorProperty

[/code]

Sometimes there are more complex properties that need default values as System.Drawing.Font where DefaultValueAttribute will not fit, two special purpose methods named

void ResetPropertyname(), bool ShouldSerializePropertyname().

if Reset method is available it will be called one Reset command, ShouldSerialize method is for (should the designer generate a line in the form.designer.cs file or not) so obviously you should serialize when the value is not the default and not serialize if the property value is changed.

[code:c#]

System.Drawing.Font f;
public System.Drawing.Font FontProperty
{
  get
  {
    if (f == null)
      return this.Font; //this should be the default value you want
    else return f;
  }
  set { f = value; }
}

void ResetFontProperty()
{
  f = null;
}
bool ShouldSerializeFontProperty()
{
  return f == null ? false : true;
}

[/code]

The DefaultPropertyAttribute just tells the designer which Property should be selected when the PropretyWindow opens (control:right click > Properties Or selected control: press F4). For example, Text is the default property of the TextBox control.

The DefaultEventAttribute tells the designer which Event should be selected when the ProperyWindow (Events Tab) opens, more over when double click the control the designer will generate an event handler method for that event. For example, Click is the default event of the Button control.

[code:c#]

[DefaultEvent("NumofClicksChanged")]
[DefaultProperty("NumOfClicks"]

public class ButtonEx : Button

[/code]

To be continued…

References:

http://msdn2.microsoft.com/en-us/library/tk67c2t8.aspx

Download Code : ButtonEx.cs (2.10 kb)

Categories
Design Time Support Uncategorized

Custom Controls Design Time Support Part 0: Introduction

In my amr-elsehemy.blogspot.com I started a design time support tutorial for custom controls but I didn't manage to finish them so I will start my blog here on amrelsehemy.net by editing my previous posts and adding new tutorials.

So if you came from my blogspot you may still find some new useful information, so lets start.

You need to be familiar with some terms when working with the design time environment .

Design Time Archticeture

[more]

Type: The Custom Control or Component that will take advantage of the design time environment.

Member(s): The members of the Type usually Properties and Events, sometimes methods.

Attributes: They are responsible to associate the Type and/or the Member(s) of the type with a class that extends design time behaviour.

Designers: They are used to customize the behavior of a component at design time, including its appearance, initialization, and interaction with the user. A designer can add, remove, or replace properties listed in a property browser for a selected component. They can provide user-defined methods that can be linked to certain component events or executed from a custom menu command, or DesignerVerb. A designer can also use services provided by a design-time environment.

Type Converters: They can be implemented to convert values between the type it is built to support and other data types that it can translate values to or from. A type converter can also provide logic to enable configuration of a property within a property browser at design time. A type converter can provide a list of standard values for a property of the type it supports at design time in a property browser. A type converter can also produce initialization code to initialize a property at design time.

UI Type Editors: They can provide a custom user interface (UI) for editing the value of a property and displaying a representation of the value of the property at design time. A UI type editor is type-specific and provides a user interface for configuring properties of the type it is built to support, or derived types which do not have an overriding attribute, at design time. A UI type editor can display a Windows Form or drop-down configuration interface for configuring a property.

Design Time Environment: The Visual Studio would be the perfect host.

Design Time Services: Services provided by the Visual Studio as ( IComponentChangeService, ISelectionService, IMenuCommandService and much more )

Forms Designer: The actual area that you interacts with, where you place controls on.

Properties Window: The special property grid window in the visual studio.

I will try to discuss each one with some few code examples to make everything clear.

References:

http://msdn2.microsoft.com/en-us/library/c5z9s1h4.aspx

Categories
My Site Uncategorized

New domain, New blog

I finally managed to buy myself a new domain, setup a new blog.

Some of you may already know me, but a brief introduction is in order for this initial post. I am a software developer on the Maisonette team at Sunshine Computer Systems, I worked with many Microsoft products in Maisonette and others including Visual Studio 2005 and 2008 Team System, Sql Server 2005 and Team Foundation Server. Working with ASP.NET 2.0, Custom Controls, log4net, WiX, windows services, GDI+ and others more.

So you might expect to see in the future posts about those.

BlogEngine.NET is an open source .NET blogging project that was born out of desire for a better blog platform. A blog platform with less complexity, easy customization, and one that takes advantage of the latest .NET features.