English

Bug: Using .NET container controls inside ArcGIS applications

Description

Forms can be created in Visual Studio .NET that are hosted inside ArcGIS applications, for example as custom property pages, or as custom Object Inspectors. In some cases problems may be encountered if certain controls have been used on the .NET form that is hosted inside ArcMap. These problems may occur when control on the .NET form has focus, when the ArcGIS application is minimized, or when focus is switched away from the ArcGIS application in some other way.

For example, this problem can be experienced by creating a custom property page in Visual Studio .NET for graphic elements, that contains a tab control that in turn contains other .NET controls. Display the custom property page in ArcMap, click on the controls contained inside the tab control, and then switch to another application.

Cause

Some Windows Forms Controls in .NET are parented in a different way to those created in other environments, for example VB 6 forms and controls or Visual C++ dialogs and controls. Due to this difference in the parenting of some .NET controls, it is possible to encounter a situation where an endless loop of Windows Messages are passed between the .NET form and the item in ArcGIS which hosts the .NET form.

Workaround

Do not use affected controls as containers.

Alternatively, for each control used in the .NET project that acts as a Container, or holds other controls within it, verify that the ContainerStyle is set to True. This verifies that the parenting of container controls is consistent and the infinite message loop does not occur. However, as the ContainerStyle is a protected member, and therefore can only be set internally to the class, new control classes must be created to achieve this.

The workaround is fully described below.

Some of the controls for which ContainerStyle is set to False by default are:
TabControl, StatusBar, Button, TextBox, PictureBox, ListView, TreeView, and ToolBar.

Some of the controls for which ContainerStyle is set to True by default are:
Form, Panel, GroupBox, and TabPage.

  1. Create a new Class which inherits from the Control class of interest.

    For example, when using a TabControl class, create a new ContainerTabControl that inherits from TabControl:

    Code:
    public class ContainerTabControl : TabControl
    {
    public ContainerTabControl()
    {}
    }

  2. Set the ContainerStyle in the constructor of this new control. For example:

    Code:
    public class ContainerTabControl : TabControl
    {
    public ContainerTabControl()
    { this.SetStyle(ControlStyles.ContainerControl, true);
    }
    }

  3. Replace all uses of the old control with the new container control. This can be done in one of two ways.

    - Remove all the old controls from the form, and recompile the project. Add the new inherited controls to the Toolbox by right-clicking the Toolbox, then navigating to the compiled project and selecting it to add the new inherited controls to the Toolbox; then add the inherited controls to the form in the usual way.

    - In the Code view of the form, replace the declarations and instantiations of the old controls with declarations and instantiations of the newly inherited forms
    Note:
    This requires editing the 'Windows Form Designer generated code' region of the form: it is generally recommended by Microsoft to not edit this region in the code editor. Making these changes may affect the project's source code; only perform this step if the project has been backed up and the consequences of the action are known.