Comparing the Windows Forms Designer Framework to the WPF Designer Framework
The WPF Designer architecture is significantly different from the Windows Forms Designer architecture, which is characterized by the IComponent interface and the System.ComponentModel namespace. If you have created custom design-time implementations for Windows Forms controls, you will notice that the WPF Designer architecture is easier to use and extend.
The WPF Designer architecture retains the TypeConverter and TypeDescriptor classes from the Windows Forms Designer object model. Most other aspects of the WPF Designer architecture are different. For more information about the Windows Forms design-time architecture, see Extending Design-Time Support.
Key Differences between the ComponentModel Framework and the WPF Framework
Differences between the WPF Designer architecture and the System.ComponentModel framework are summarized in the following table.
ComponentModel framework |
WPF Designer framework |
---|---|
Based on IComponent, IContainer, and ISite interfaces. |
Based on the FrameworkElement class. |
Relies on design-time services provided by a host. |
Designers declaratively publish minimum requirements. |
Dedicated designer type for each control type. |
Any number of features may operate on a control type. |
Metadata hard-coded for each control type; fixed at compile time of the control. |
Metadata deployed in a separate assembly; may be customized or replaced by tools. This enables updating the design-time metadata independently of the control. |
An IDesignerHost holds designer state. |
The EditingContext class holds designer state. |
Services are collected and shared with an IServiceContainer implementation. |
The EditingContext class holds service references. |
The BehaviorService manages keyboard, mouse, and command interactions. |
The WPF Designer tool architecture manages keyboard, mouse, and command interactions. |
Editing object model consists of the run-time controls, with late-bound access through the PropertyDescriptor class. |
Editing object model provides a layer of indirection to abstract the run-time controls. Category editors allow editing of multiple properties in a single UI. |
IComponent vs. FrameworkElement
WPF elements derive from the FrameworkElement class, which provides the connection between WPF core services and framework-level element classes.
WPF elements do not implement the IComponent interface. This is one of the fundamental reasons why the WPF Designer does not use the System.ComponentModel framework. This means WPF controls are never sited. Therefore, WPF controls cannot request designer services from the System.ComponentModel design environment.
Design-time Services
Designers in the System.ComponentModel framework request services from the design environment. In the WPF Designer framework, you can accomplish most tasks without querying the environment for services.
In the System.ComponentModel framework, designer services are not guaranteed to be present in a designer host, which means custom designer code must always check for a null reference after a call to the GetService method. Designer code must degrade gracefully when a service is not present, and in many cases this constraint cannot be met.
In the WPF Designer framework, a custom designer declaratively publishes its minimum requirements. If a host is unable to meet the contract, the designer does not load. This makes the overall implementation simpler and more robust.
Dedicated Designer Types and Decoupling Metadata
In the System.ComponentModel framework, a designer type is associated with its corresponding component through the DesignerAttribute metadata attribute. This means the relationship is established at compile time, forcing a hard-coded dependency between the component's run-time and design-time behavior. To attach a different designer, you must change the DesignerAttribute declaration and recompile the component's code base.
In the WPF Designer, designer metadata is factored into a separate assembly, physically decoupling it from the run-time implementation. This freedom means that different tools can present completely different design experiences for the same run-time type. For more information, see AttributeTable.
Editing Object Model
In the System.ComponentModel framework, custom designers access controls in a late-bound manner through the PropertyDescriptor class. This rule is not enforced by the design environment, and bugs result if a developer forgets to access a control through the PropertyDescriptor class.
In the WPF Designer framework, custom designers interact with run-time controls though an editing object model. This model provides a layer of indirection which abstracts the controls into a model and a view. This object model eliminates the need to access controls through the PropertyDescriptor class.
Similarity to the ComponentModel Designer Framework
Editing contexts are the basis for the WPF Designer. The EditingContext class contains contextual state about a designer.
The editing context is conceptually similar to the IDesignerHost interface in the System.ComponentModel.Design namespace. The IDesignerHost interface defines many features in its interface, but the EditingContext class focuses on only the data and behavior features.
The editing context exposes services in a way that is similar to the IServiceContainer interface. The editing context supports enumeration and does not support removing services once they are added. For more information, see Editing Context Architecture.
Differences in Attribute Usage
Designer attributes have different meanings in the WPF Designer and Windows Forms architectures. The following table describes how designer-related attribute usage differs between the two frameworks.
Attribute |
Windows Forms Properties window |
WPF Designer Properties window and Expression Blend Property Inspector |
---|---|---|
Specifies the value to pass to a property to cause the property to get its value from another source. This is known as ambience. |
N/A |
|
Specifies whether a property or event should be displayed in the Properties window. |
Specifies whether a property or event should be displayed in a Properties window. When explicitly set to true on a property that is normally not shown, that property will be shown. |
|
Specifies the name of the category in which to group the property or event when displayed in a PropertyGrid control set to Categorized mode. |
Specifies the name of the category in which to group the property when displayed in a Properties window. |
|
Specifies the default value for a property. |
For CLR data types, specifies the default value for a property. Ignored on dependency properties. |
|
Specifies a description for a property or event. |
N/A |
|
Specifies the display name for a property, event, or public void method that takes no arguments. |
Specifies the name that will appear in the Properties window for the property this attribute is applied to. |
|
Specifies the editor to use to change a property. |
Specifies the editor to use to change a property, including multi-property category editors. |
|
N/A |
EditorBrowsableState.Advanced puts a category editor or property into the Advanced expander. |
|
Specifies the context keyword for a class or member. |
N/A |
|
Specifies whether a property should be localized. |
N/A |
|
Indicates that an object's text representation is obscured by characters, such as asterisks. |
N/A |
|
Specifies whether the property this attribute is bound to is read-only or read/write at design time. |
Specifies whether the property this attribute is bound to is read-only or read/write at design time. Properties that are marked with the ReadOnlyAttribute will display the read-only object to string editor in the Property Inspector. |
|
Indicates that the Properties window should refresh when the associated property value changes. |
N/A |
|
Specifies what type to use as a converter for the object this attribute is bound to. |
Specifies what type to use as a converter for the object this attribute is bound to. |
|
Specifies the default event for a component. |
Specifies the default event for a component, which determines the event handler to be created on double-click. |
|
Specifies the default property for a component. |
Specifies the default property for a component, which determines which property is selected by default. |
|
Specifies the class used to implement design-time services for a component. |
N/A |
|
Specifies that the designer for a class belongs to a certain category. |
N/A |
|
Represents an attribute of a Toolbox item. |
N/A |
|
Specifies the filter string and filter type to use for a Toolbox. |
N/A |
|
N/A |
Used to prevent a type from showing up in the Toolbox when an assembly is examined for types to add to the Toolbox. |
|
N/A |
Used to specify which items are added to the combo box for the collection editor or sub-properties editor. Allows a factory to be specified that customizes the creation. |
|
N/A |
Used to specify the order in which properties will show up in the Properties window. |
The following attributes are used in the WPF Designer framework, but not in the Windows Forms Designer framework.
Differences in Specifying Toolbox icons
In the Windows Forms Designer framework, you specify a Toolbox icon for your custom control by applying the ToolboxBitmapAttribute to your control class.
In the WPF Designer framework, you use an embedded resource and a naming convention to specify a Toolbox bitmap. In addition, you use the ToolboxBrowsableAttribute to restrict which types in an assembly are available for populating a Toolbox.
Differences in Specifying Metadata
In Windows Forms, designer metadata is specified declaratively, by applying attributes such as DesignerAttribute.
In the WPF Designer architecture, designer metadata is specified in an AttributeTable.