Поделиться через


Troubleshooting Design-Time Development

Caution

This content was written for .NET Framework. If you're using .NET 6 or a later version, use this content with caution. The designer system has changed for Windows Forms and it's important that you review the Designer changes since .NET Framework article.

The following common issues can occur when you create a custom design-time experience for your Windows Forms components and controls:

  • Unable to Compile

  • Unable to Debug at Design Time

  • Compiler Error: "The type or namespace name 'type name' could not be found."

  • Design-Time Error: "Failed to create component 'component name.'"

  • Debugging Error: "Illegal cross-thread operation: Control 'control name' accessed from a thread other than the thread it was created on."

  • Design-Time Error: "Cannot open a designer for the file because the class within it does not inherit from a class that can be visually designed."

  • Glyphs Remain After Component Is Deleted

  • Default Designer Behavior Obscured by Custom Behavior

  • Designer Events Raised in an Unintended Manner

  • Collections Fail to Serialize

  • Designer Fails to Acquire an UndoEngine Reference

  • Design Environment Does Not Recognize Changes to the Component's Properties

  • DesignerAttribute Syntax

  • Refreshing the Design Environment After Making Changes to the Component or Designer

  • FxCop Warning on Newly Generated Windows Form: DoNotInitializeUnnecessarily

  • Partial Classes and the Windows Forms Designer

  • Legacy Custom Controls Cause Unexpected Behavior in the Designer

  • Smart tag in a hosted designer raises an exception

  • Component Icon Does Not Appear in Toolbox

Unable to Compile

For a significant part of design-time development, you must add a reference to the design-time assembly, System.Design.dll. This assembly is not included in the .NET Framework 4 Client Profile. To add a reference to System.Design.dll, you must change the project's Target Framework to .NET Framework 4.

Unable to Debug at Design Time

There are two ways to debug your design-time code:

  • Place MessageBox.Show calls at strategic points in your code.

  • Attach another instance of Visual Studio to debug the design environment of the first instance.

For more information, see How to: Access Design-Time Services.

Topic Location
Walkthrough: Debugging Custom Windows Forms Controls at Design Time Windows Forms Controls
Troubleshooting Control and Component Authoring Windows Forms Controls
Walkthrough: Debugging Custom Windows Forms Controls at Design Time Windows Forms Controls
Troubleshooting Control and Component Authoring Windows Forms Controls
Walkthrough: Debugging Custom Windows Forms Controls at Design Time Windows Forms Controls
Troubleshooting Control and Component Authoring Windows Forms Controls
Walkthrough: Debugging Custom Windows Forms Controls at Design Time Windows Forms Controls
Troubleshooting Control and Component Authoring Windows Forms Controls

Compiler Error: "The type or namespace name 'type name' could not be found"

You should reference the System.Design assembly. Designer-related types are located in the System.Design assembly. This includes types in the System.Windows.Forms.Design and System.ComponentModel.Design namespaces.

Also, be sure to import the namespaces you need using the Imports or using keywords. For more information, see How to: Access Design-Time Support in Windows Forms.

Design-Time Error: "Failed to create component 'component name'"

You can receive this error when you are creating your component or control on the design surface from the Toolbox. The following table shows the two likely causes for this error.

Cause

Description

Notes

Missing default constructor

Your component or control must have a default constructor, which is a constructor with no parameters.

The design environment requires a default constructor to be able to create an instance of your type.

Component is a generic type

Your component or control cannot be a generic type, which is also called a template type or a parameterized type. The design environment does not support generic types.

If your generic type derives from UserControl and you attempt to run it in Visual Studio's UserControl Test Container, you will receive the following error:

Failed to create UserControl 'name'

The error message was 'Cannot create a type for which Type.ContainsGenericParameters is true.'

The UserControl will be removed from the list.

Although your components and controls cannot be generic types, they can use generic types.

Design-Time Error: "Value cannot be null. Parameter name: 'component name'"

You can receive this error when you are creating your component or control on the design surface from the Toolbox. The most likely cause is that you are trying to use a component or control that was built to a 64-bit assembly. The Visual Studio design environment does not support 64-bit components.

Debugging Error: "Illegal cross-thread operation: Control 'control name' accessed from a thread other than the thread it was created on."

If you use multithreading in your Windows Forms applications, you must be careful to make calls to your controls in a thread-safe way. This exception is raised by the debugger and does not appear at run time, but you are strongly advised to fix this problem when you see it. For more information, see How to: Make Thread-Safe Calls to Windows Forms Controls.

Design-Time Error: "Cannot open a designer for the file because the class within it does not inherit from a class that can be visually designed"

The file with your component or control can contain multiple class definitions, but the first class in the file must be one that you can design. The first class in the file must implement the IComponent interface, or it must derive from the Component class or a class that derives Component.

Glyphs Remain After Component Is Deleted

If your custom designer creates any Adorner objects, you must delete them from the design surface when your designer goes out of scope. Call BehaviorServiceAdornerCollection.Remove in your designer's Dispose method, to clear Glyph objects and related Adorner and Behavior objects. For more information, see How to: Extend the Appearance and Behavior of Controls in Design Mode.

Default Designer Behavior Obscured by Custom Behavior

The default control designer creates a glyph that covers the entire control on the design surface. This is named the body glyph. If your custom control designer creates a glyph with the same bounds as the body glyph, it will obscure the underlying Behavior implementation associated with the body glyph. This prevents default features such as smart tags and resize glyphs from appearing.

You cannot pass messages among Behavior objects, so you cannot handle a mouse message and forward it to any underlying Behavior objects. When you implement a glyph that covers the entire control, you are responsible for the entire appearance and behavior of your custom design experience.

Designer Events Raised in an Unintended Manner

If your custom designer attaches event handlers to designer events such as ComponentRemovedActiveDesignerChanged, and SelectionChanged, you must detach your event handlers in your designer's Dispose method.

Failing to do this can result in unintended behavior at design time. The following list shows some of the symptoms that can occur:

  • Error message box: "An error occurred while processing this command."

  • Error message box: "Object reference not set to an instance of an object."

  • Event handlers called inappropriately when components are deleted or designers are closed.

Collections Fail to Serialize

If you want your custom component or control's collection property to be serialized, apply the DesignerSerializationVisibilityAttribute and set it to Content. For more information, see How to: Serialize Collections of Standard Types with the DesignerSerializationVisibilityAttribute.

Designer Fails to Acquire an UndoEngine Reference

If you attempt to acquire a reference to the UndoEngine service while a form is loading, the GetService method returns null.

The UndoEngine service is not created and enabled until the form has completed its load phase. After the form is loaded, subsequent calls to GetService will return an UndoEngine reference.

In general, you should seldom require a reference to the UndoEngine directly. Those cases in which you do need it are usually caused by a user action and occur after the designer is loaded.

Design Environment Does Not Recognize Changes to the Component's Properties

The design environment does not recognize changes to your component or control if you set properties directly. For events like ComponentChanged to be raised, you must set the value of your component's properties with the PropertyDescriptor.SetValue method. This notifies the design environment of the property change, enabling the design surface and PropertyGrid controls to update correctly. For more information, see How to: Extend the Appearance and Behavior of Controls in Design Mode.

DesignerAttribute Syntax

You attach your custom designer to the control it designs by applying the DesignerAttribute to the control.

You must precisely specify the DesignerAttribute parameters, otherwise the design environment will not load your custom designer.

Refreshing the Design Environment After Making Changes to the Component or Designer

When you make changes to the design-time aspects of a component, you must rebuild the component's project. In addition, if there is another Windows Forms project that is currently open and uses this component, you will probably need to refresh the project to see the changes. Typically, you must close and reopen the design window containing the component.

FxCop Warning on Newly Generated Windows Form: DoNotInitializeUnnecessarily

The Windows Forms Designer generates the following code for Windows Forms Application projects in C#.

private System.ComponentModel.IContainer components = null;

Depending on which FxCop rules are in effect, FxCop may produce the "DoNotInitializeUnnecessarily" warning. This is because null is the Common Language Runtime (CLR) default for reference properties.

If the designer did not initialize the components field to null, the C# compiler would produce the following warning:

"Form1.components is never assigned to, and will always have its default value null."

You can suppress the FxCop warning with SuppressMessageAttribute, but this can cause maintenance issues if the class name is changed. Therefore, it is recommended that you ignore the FxCop warning.

Partial Classes and the Windows Forms Designer

By default, the Windows Forms Designer emits designer serialization code into a dedicated file that is separate from your component's main file. For example, in a Windows Forms Application project, the definition for the Form1 class is split into two files, as shown in the following table.

File (C# file names)

Function

Form1.cs

Main class file

Form1.Designer.cs

Designer-emitted code

File (VB file names)

Function

Form1.vb

Main class file

Form1.Designer.vb

Designer-emitted code

In general, you do not need to modify the code emitted by the Windows Forms Designer. Edit the main class file instead.

The Windows Forms Designer uses the partial keyword to divide the implementation of Form1 into two separate files. This prevents the designer-emitted code from being interspersed with your code. For more information about the partial keyword, see Partial Classes and Methods (C# Programming Guide) and Partial (Visual Basic).

The Windows Forms Designer does not support dividing a designable type's definition into more than two partial implementations. This restriction includes creating a new class file that contains a third partial definition of the type, as well as adding a third partial class definition of the type in either the main file or the designer file. Members defined this way will not be visible in the Windows Forms Designer.

Legacy Custom Controls Cause Unexpected Behavior in the Designer

When types are invalidated in the designer, the ComponentSerializationService performs a partial reload to refresh the designer with the updated types. Versions of Visual Studio preceding Visual Studio 2005 completely reloaded the designer. The partial reload behavior in Visual Studio 2005 is faster than a complete reload, and it also preserves the undo stack.

Components and corresponding serializers authored before Visual Studio 2005 may not be able to accommodate a partial reload. Components and controls may cause unexpected behavior because they were authored to deserialize only during a full reload. Symptoms include stack overflows, hangs, or blank regions in the Windows Forms Designer when legacy controls are present.

You can revert to the full reload behavior by adding the following setting to the devenv.exe.config file. If you installed Visual Studio 2005 to the default location, this file is in the C:\Program Files\Microsoft Visual Studio 8\Common7\IDE folder.

<appSettings>
   <add key="EnableOptimizedDesignerReloading" value="false" />
</appSettings>

Smart tag in a hosted designer raises an exception

If you are hosting a designer outside Visual Studio, your smart tags may raise a NullReferenceException. To resolve this issue, provide an IUIService reference in your designer and implement the Styles property. In the IDictionary exposed by Styles, assign a new Font as the element specified by the "DialogFont" key, as shown in the following code fragment.

Styles["DialogFont"] = new Font(...);

Component Icon Does Not Appear in Toolbox

In Visual Studio, when you use ToolboxBitmapAttribute to associate an icon with your custom component, the bitmap does not appear in the Toolbox for autogenerated components. To see the bitmap, reload the control by using the Choose Toolbox Items dialog box. For more information, see Toolbox Icons.

See Also

Tasks

How to: Access Design-Time Services

Concepts

Design-Time Errors in the Windows Forms Designer

Other Resources

Extending Design-Time Support