Show environment bar in Dynamics AX forms

When working with multiple Dynamics AX environments, it’s quite useful to have a visual reminder of which environment you’re working in.

It is possible to use the instance name in the client configuration to provide this hint, but the instance name is not validated, nor does it indicate to the client which instance to connect to.  The connection is established only based on the host name, port name and WSDL port.  It is, in fact, possible to specify anything at all as the instance name:

My production server does NOT have an instance named MickeyMouse.  I promise…  Really…

Connecting to the AX instance shows this in the status bar:

This also relies on the user having enabled this information to be shown in the status bar, and even if they have, this will eventually come to bite you when you start copying configurations and configuration files, so a better solution is needed.

The following shows how to add an information bar at the bottom of each form, like this:

This has been developed and tested on AX2012R3, but it will most likely work unchanged or with only minor changes on other versions of AX2012, possibly even on AX2009 and older, although more substantial changes are likely to be necessary.  The general concept would remain the same, though.

First we need to add a couple of local members to the SysSetupFormRun class:

// This is a framework class. Customizing this class may cause problems with future upgrades to the software.
public class SysSetupFormRun extends FormRun
{
 SysWorkflowFormControls workflowControls;
 // <GEERU>
 // Event listeners list
 List listeners_W;
 // </GEERU>

 // EB 11/02/2016: Add environment indicator ==>
 FormGroupControl EB_envBottomGroup;
 FormWindowControl EB_envImage;
 FormStaticTextControl EB_envStatic;
 FormButtonControl EB_envHideButton;
 // EB 11/02/2016: Add environment indicator <==

#if.never
 #define.CurrentVersion(1)
 #localmacro.CurrentList
 #endmacro
#endif
}

Next, override the run() method, to make sure that the elements needed for the environment indicator are created every time a form is opened.

// EB 11/02/2016: Add environment indicator
public void run()
{
  str message;
  int rgb;
  str dbName;

  super();

The first thing I’m going to do is to call super() to let the system initialise the form, before I start customising it.

Next I’m checking what type of form this is.  We don’t want to show the indicator on embedded forms such as web parts, drop dialogs, etc.  This code makes sure it only shows on traditional forms and list pages.

if( this.isDetached() && ( this.design().style() != FormStyle::DropDialog ) )
 {

In my case, I can determine which environment I’m running in by checking the database name, as we have a consistent naming convention around here.  I choose a suitable text and colour based on the database name returned.

dbName = SysSQLSystemInfo::construct().getloginDatabase();
dbName = subStr( dbName, strFind( dbName, "_", 1, strLen( dbName ) ) + 1, strLen( dbName ) );

switch( dbName )
{
  case "Dev":
    message = "Development environment - Be prepared for weirdness and random crashes";
    rgb = WinAPI::RGB2int( 160, 240, 255 );
    break;
  case "Test":
    message = "Test environment";
    rgb = WinAPI::RGB2int( 160, 255, 160 );
    break;
  case "Staging":
    message = "Staging environment";
    rgb = WinAPI::RGB2int( 255, 255, 0 );
    break;
 case "Live":
   return;
 }

Next I’m going to add the controls to the form through X++ code.

EB_envBottomGroup = this.design().addControl( FormControlType::Group, "EB_envBottomGroup" );
EB_envImage = EB_envBottomGroup.addControl( FormControlType::Image, "EB_envImage" );
EB_envStatic = EB_envBottomGroup.addControl( FormControlType::StaticText, "EB_envStatic" );
EB_envHideButton = EB_envBottomGroup.addControl( FormControlType::Button, "EB_envHideButton" );

EB_envBottomGroup is a group control that will contain the other controls.  I size and style it before moving on to the other controls.

EB_envBottomGroup.widthMode( FormWidth::ColumnWidth );
EB_envBottomGroup.heightMode( FormHeight::Auto );
EB_envBottomGroup.colorScheme( FormColorScheme::RGB );
EB_envBottomGroup.backStyle( FormBackStyle::Opaque );
EB_envBottomGroup.backgroundColor( rgb );
EB_envBottomGroup.frameType( FormFrameType::None );
EB_envBottomGroup.topMargin( 5 );
EB_envBottomGroup.bottomMargin( 0 );
EB_envBottomGroup.leftMargin( 5 );
EB_envBottomGroup.rightMargin( 5 );

EB_envImage is just an icon, used to make the indicator bar a bit more interesting.  Completely optional, of course.  I am using resource ID 918 here, but if you want a different one, have a look through the embedded resources by using the tutorial_Resources form.

EB_envImage.width( 15, FormWidth::Auto );
EB_envImage.height( 15, FormHeight::Auto );
EB_envImage.leftMode( FormLeft::LeftEdge );
EB_envImage.imageResource( 918 );
EB_envImage.imagemode( 1 );
EB_envImage.backStyle( FormBackStyle::Transparent );
EB_envImage.showLabel( false );

Next, EB_envStatic is a static text control where I display the environment indicator text.

EB_envStatic.alignment( FormAlignment::Center );
EB_envStatic.fontSize( 10 );
EB_envStatic.text( message );

The final control is a button which can be used to hide the environment indicator.  Perhaps it is taking up too much space, or it needs to be hidden in order to do a screen shot.  For whatever reason, it is good practice to allow the user to hide it when necessary.  I’m using resource ID 8008 here, which is a small “Close” icon.  Use whatever other icon you want, but be mindful of the size of the environment bar.  It should not be too large, or it will take up too much space, and some icons don’t scale that well to small sizes.

EB_envHideButton.width( 15, FormWidth::Auto );
EB_envHideButton.height( 15, FormHeight::Auto );
EB_envHideButton.leftMode( FormLeft::RightEdge );
EB_envHideButton.normalResource( 8008 );
EB_envHideButton.buttonDisplay( FormButtonDisplay::ImageOnly );
EB_envHideButton.backStyle( FormBackStyle::Transparent );
EB_envHideButton.style( ButtonStyle::Link );

Finally, we have to register an override method so we can capture the click event and actually hide the environment indicator.

    EB_envHideButton.registerOverrideMethod( methodStr( FormButtonControl, clicked ), methodStr( SysSetupFormRun, EB_hideEnvButton_Clicked ), this );
  }
}

That’s it for the run method.  Now add a new method to the SysSetupFormRun class and call it EB_hideEnvButtonClicked.  (Of course, the actual prefix is totally up to you and the naming conventions you follow.)

// EB 11/02/2016: Add environment indicator
public void EB_hideEnvButton_Clicked( FormWindowControl _caller )
{
  EB_envBottomGroup.visible( false );
}

That’s it.  Recompile the class and update the CIL code.  Users will then get the environment indicator at the bottom of their forms.

Please, make sure you do this in a dev/test environment first, and test it before loading to production.

An XPO containing this modification is available here: Class_SysSetupFormRun.zip

2 thoughts on “Show environment bar in Dynamics AX forms”

    1. Happy it worked.
      I’ve been juggling a large number of environments for many years and the indicator bar has saved my behind more than once.

Leave a Reply

Your email address will not be published. Required fields are marked *