Base Designer Classes
All designers implement the IDesigner interface, which defines the basic designer interface methods. The .NET Framework also provides a set of base designer classes that provide methods that can be useful to designers that support specific types of components or controls.
IDesigner Interface
A designer class must implement the System.ComponentModel.Design.IDesigner interface, as shown in the following code example.
Public Interface IDesigner
Sub Dispose()
Sub Initialize(component As IComponent)
' Other methods.
...
ReadOnly Property Component() As IComponent
' Other properties.
...
End Interface
[C#]
public interface IDesigner {
void Dispose();
void Initialize(IComponent component);
// Other methods.
...
IComponent Component {
get;
}
// Other properties.
...
}
The Initialize method of an IDesigner is called after the component for the designer has been sited and initialized, and the designer has been created. You can override the Initialize method to perform actions that should occur at component or designer initialization time. You cannot replace the constructor initialization of the component, but you can augment it or reset the properties that it initializes. The Component property of an IDesigner is set through this initialization method. You should always call base.Initialize(
component)
from your Initialize method if you override this method. You can access the component of an IDesigner from its Component property.
The Component property provides access to the component that the designer is associated with. This property is set when the designer object is first created and its Initialize method is called. The component has a site associated with it, and the designer can use this site to obtain services from the designer's host.
The DoDefaultAction method is called when a component or control is double-clicked.
The Verbs property can be overridden to return a DesignerVerbCollection that contains the objects necessary to extend the menu items of a shortcut menu for a component.
The Dispose method is invoked when the designer object needs to be destroyed. It is called whenever a component is removed from the design container.
Base Designer Class for Components
The System.ComponentModel.Design.ComponentDesigner class implements the IDesigner and IDesignerFilter interfaces to offer additional methods that can be useful to some designers of components.
Base Designer Class for Windows Forms Controls
The base designer class for Windows Forms controls is System.Windows.Forms.Design.ControlDesigner. This class derives from ComponentDesigner and provides additional methods useful for customizing the appearance and behavior of a Windows Forms control. For a sample implementation of a Windows Forms designer, see Windows Forms Designer Sample.
Base Designer Class for ASP.NET Server Controls
The base designer class for ASP.NET server controls is System.Web.UI.Design.ControlDesigner. This class provides the base functionality for custom design-time HTML rendering. Other base classes for tasks such as template editing are described in Design-Time Support for Web Forms.
Standard Designers
The .NET Framework SDK provides a set of designers to support specific types of components. These designers are named after the components they design, with the word Designer suffixed. For example, the designer for the class System.Windows.Forms.Control is System.Windows.Forms.Design.ControlDesigner.
Common Designer Functionality
Accessing Design-Time Services from a Designer
Most types of design-time services can be requested through a GetService method by passing the type of the service to request. There is a GetService method on Component and ComponentDesigner, and a GetService method on IServiceProvider, which is implemented by the ISite returned by the Site property of a Component sited in design mode. The following code shows how to obtain an IDesignerHost service interface and an IMenuCommandService using a GetService method.
The following code demonstrates how to obtain a service from a design mode service provider interface.
' Obtain an IDesignerHost service from the design-time environment.
Dim host As IDesignerHost = CType(Me.Component.Site.GetService(GetType(IDesignerHost)), IDesignerHost)
' Obtain an IMenuCommandService service.
Dim mcs As IMenuCommandService = CType(Me.Component.Site.GetService(GetType(IMenuCommandService)), IMenuCommandService)
[C#]
// Obtain an IDesignerHost service from the design-time environment.
IDesignerHost host = (IDesignerHost)this.Component.Site.GetService(typeof(IDesignerHost));
// Obtain an IMenuCommandService service.
IMenuCommandService mcs =
(IMenuCommandService)this.Component.Site.GetService(typeof(IMenuCommandService));
Accessing Project Components from a Designer
A designer can obtain access to the components within a design mode document by accessing the Components collection of the Container property of an IDesignerHost service interface. The following example code shows how to access the components in the current design-mode project.
' Obtains an IDesignerHost service from the design-time environment.
Dim host As IDesignerHost = CType(Me.Component.Site.GetService(GetType(IDesignerHost)), IDesignerHost)
' Gets the components container for the current design-time project.
Dim container As IContainer = host.Container
' The host.Container IContainer contains each IComponent in the project.
[C#]
// Obtains an IDesignerHost service from the design-time environment.
IDesignerHost host = (IDesignerHost)this.Component.Site.GetService(typeof(IDesignerHost));
// Gets the components container for the current design-time project.
IContainer container = host.Container;
// The host.Container IContainer contains each IComponent in the project.
Once you have access to the components collection, you can use System.Type methods and System.Reflection objects to identify types and set the values of properties of components. You can also create components using the CreateComponent method of the IDesignerHost interface.
Extending a Designer
When you derive from a component that has an associated designer, the designer of the base class is associated with the derived component by default. You can associate a different designer with your component by applying a DesignerAttribute attribute that specifies the type of designer to associate with the component. It is common for a derived component to have a designer that extends the base designer.
To extend a designer
- Define a class that derives from the base designer class.
- Associate the new designer class with your component by applying a DesignerAttribute.
The following code example defines a designer that extends System.Web.UI.Design.Webcontrols.LabelDesigner and associates it with a custom label that extends System.Web.UI.WebControls.Label.
Namespace MyControls.Design
Public Class MyLabelDesigner
Inherits System.Web.UI.Design.WebControls.LabelDesigner
End Class
End Namespace
Namespace MyControls
<Designer(GetType(MyControls.Design.MyLabelDesigner))> _
Public Class MyLabel
Inherits System.Web.UI.WebControls.Label
End Class
End Namespace
[C#]
namespace MyControls.Design {
public class MyLabelDesigner : System.Web.UI.Design.WebControls.LabelDesigner {}
}
namespace MyControls {
[Designer(typeof(MyControls.Design.MyLabelDesigner))]
public class MyLabel : System.Web.UI.WebControls.Label {}
}
Note If you are defining a designer for a class that is sealed, or if you do not want other classes to use or inherit from your designer, you can make your designer class internal to your assembly. The designer host will still be able to create an instance of your designer, but it will not contribute to the public object model.
See Also
Custom Designers | Enabling Property Filtering | Designer Verbs | Windows Forms Designer Sample | Web Forms Templated Data-Bound Control Designer