Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Add logic to displays with CodeBehind.

How-to Guides Pillars Operator → Displays → CodeBehind | How-To Guide | Reference


Displays CodeBehind (Reference) provides server-side scripting capabilities for displays, with pre-defined event methods and custom functions in VB.NET, C#, or JavaScript (HTML5-only displays).

CodeBehind enables:

  • Display lifecycle event handling
  • Custom methods for user interactions
  • Mouse and keyboard event processing
  • Custom Properties for local variables
  • Integration with Display namespace
  • Automatic language conversion (VB.NET ↔ C#)

Access via Displays → Draw → CodeBehind tab.


Table of Contents
maxLevel2
minLevel2
indent10px
excludeSteps
stylenone


Language Support

Portable and WPF Displays

  • VB.NET - Visual Basic syntax
  • C# - C-Sharp syntax
  • Auto-conversion between languages
  • Note: C# is more restrictive on type conversions

HTML5-Only Displays

  • JavaScript tab appears alongside VB.NET/C#
  • Both execute side-by-side in web runtime
  • Legacy approach (WebAssembly preferred)
  • Similar method structure to .NET languages

Pre-defined Methods

Every display includes these event handlers:

MethodTriggered WhenPurpose
DisplayOpening()Display starts openingInitialize variables, setup
DisplayIsOpen()While display remains openContinuous updates, monitoring
DisplayClosing()Display starts closingCleanup, save state
DialogOnOK()OK button pressed (dialogs only)Validate input, return 1 to close, 0 to prevent

Example Structure

csharp

public void DisplayOpening()
{
    // Initialize display
}

public void DisplayIsOpen()  
{
    // Called continuously while open
    // Use sparingly for performance
}

public void DisplayClosing()
{
    // Cleanup before close
}

public int DialogOnOK()
{
    // Dialogs only - validate and return
    if (ValidateInput())
        return 1; // Allow close
    else
        return 0; // Prevent close
}

Custom Properties

Local variables exclusive to the display instance:

Benefits

  • Reduce communication points
  • Store display-specific state
  • Access from both display and CodeBehind
  • Link to tags for extended functionality

Limitations

  • Data doesn't persist between pages
  • Specific to display instance
  • Lost when display closes

Runtime Methods

csharp

// Set property value
SetCustomPropertyValue("PropertyName", value);

// Get property value
var value = GetCustomPropertyValue("PropertyName");

// Get all as string
string allProps = GetCustomPropertiesAsString();

// Clear all properties
ClearCustomProperties();

See → Custom Properties for detailed documentation.


Performance Considerations

UI Blocking

  • CodeBehind runs on client thread
  • Display locks during execution
  • User cannot interact while code runs

Solutions

  1. Use Async Functions

csharp

   public async void DisplayOpening()
   {
       await Task.Run(() => LongRunningOperation());
   }
  1. Offload to Scripts
    • Use Script Tasks for heavy processing
    • Run on server or background thread
    • Prevents UI freezing
  2. Optimize Code
    • Minimize DisplayIsOpen() logic
    • Cache calculations
    • Avoid loops in event handlers

Display Namespace Access

CurrentDisplay Object

Special object available in CodeBehind:

csharp

// Access current display properties
this.CurrentDisplay.Width
this.CurrentDisplay.Height
this.CurrentDisplay.Name

// Get display framework element
this.CurrentDisplay.GetThis()

Opening Displays

Multiple methods available:

MethodAuto-Updates on RenameUsage
@Display.PageName.Open()YesPreferred for pages
@Display.PageName.NewPopup()YesCreate popup instance
@Client.OpenDisplay("PageName")NoString-based navigation
@Client.NewPopup("PageName")NoString-based popup

Mouse Wheel Example

csharp

The CodeBehind tab serves as a platform for defining functions linked to a display, written in either standard VB.Net or C# for Portable WPF Displays.  Displays targeting only HTML5 also allows JavaScript code. 

The CodeBehind functions have entry points executed when opening, closing, or while the display is open, based on your code configuration. They can also hold methods invoked by Keyboard or Mouse actions in the display.

CodeBehind enables you to script custom functionalities and responses to user inputs or system changes.

On this page:

Table of Contents
maxLevel3
stylenone

CodeBehind Editor

The editor used for the CodeBehind is the same one used for Scripts. See the page Scripts Code Editor for details of its user interface. 

You can switch between VB.Net and C#, and the system automatically converts existing code to the chosen language. 

The ability to switch between VB.Net and C# is a powerful feature that allows developers to leverage the strengths of both languages, but due differences on the languages, it is possible a VB.NET code when changed to C# will present errors, as C# is more restrictive on type conversion. 

When using your own DLLs, assembly references, seeScripts ? References.

Pre-defined Methods and Custom .NET Variables

Pre-defined Methods

The CodeBehind of each display includes a set of pre-defined methods, designed to streamline common display events:

  • DisplayOpening(): Triggered when a display is in the process of opening.
  • DisplayIsOpen(): Regularly called throughout the duration the display remains open.
  • DisplayClosing(): Activated when a display is closing.
  • DialogOnOK(): Invoked when the OK button on a dialog display is pressed. Returning 1 permits the dialog to close, while returning 0 prevents its closure.

Custom .NET Variables and Methods

In addition to pre-defined methods, CodeBehind allows for the incorporation of custom .NET variables and methods, for example as UI handles for Mouse Actions.

Custom Properties Extension

Alongside these methods, displays also support the use of Custom Properties Extensions. These properties serve as local variables exclusive to a particular display and can be accessed both within the display itself and in CodeBehind. Custom Properties can also be linked to tags to increase their functionality. One significant advantage of employing custom properties is the potential reduction of communication points while preserving project functionality.

Several runtime methods are available for managing Custom Properties, including methods for retrieving and setting property values, obtaining all properties as a string, and eliminating all custom properties. Note, however, that the logic programmed with Custom Properties is strictly valid for the specific display they're attached to, indicating that data cannot be preserved from one page for use on another.

For information about CustomProperties and their associated methods, see Custom Properties.

Code Execution Performance

When the CodeBehind runs on the client side, the display locks while the code is running (This can be circumvented by using Async functions). For lengthy procedures, opt for Scripts (tasks and classes) to prevent displays from locking for too long.

Code execution efficiency is crucial in HMI SCADA systems. Long running code can block the user interface, leading to poor user experience. Always strive to optimize your CodeBehind routines and consider offloading heavy processing tasks to the server or background processes.

Managing Multiple Popups

FactoryStudio provides diverse methods to manage and interact with displays and popups, including Display.Open, Display.NewPopup, Client.OpenDisplay, and Client.NewPopup, each with its own unique syntax and behavior. These methods provide flexibility in how new displays or popups are opened and handled in your project.

One key consideration is the difference between @Display and @Client methods. For instance, the software automatically updates the method in @Display if the display name changes, but not in @Client methods, which require manual updates.

Moreover, while utilizing labels as parameters for symbols can streamline your project setup, be aware of potential limitations when combining NewPopup input labels and Symbols. A common workaround is to use individual Popups for each symbol.

Online Configuration is another powerful tool for real-time project updates directly from the Engineering Environment.

For an in-depth understanding and examples of managing multiple popups in FactoryStudio, please visit Multiple Popups.

Knowledge of the available methods and their distinct behaviors can greatly enhance the flexibility and interactivity of your project.

Working with the Display Namespace

The Display and Client namespaces have methods used to control the Operator User Interface, for instance with the methods to open a new display.

There are several ways to open a new display or popup, such as Display.<Name>.Open, Display.<name>.NewPopup, Client.OpenDisplay, and Client.NewPopup. Each method has specific characteristics and behaviors that should be considered when using them.

In addition, the namespace includes a series of useful methods like Close(), GetCustomPropertiesAsString(), SetCustomProperties(), and SetCustomPropertyValue(), which allow you to manage and customize display properties.

For more information, see Objects and Namespaces

The Displays CodeBehind has also access to a special pre-defend object, CurrentDisplay, which has properties and methods related the display connected with the CodeBehind.

Example: Mouse Wheel Event in CurrentDisplay

To capture the mouse wheel event of a display and configure the Display.ZoomLevel of a page from it, use the following code in the CodeBehind to zoom in and out using the mouse wheel.

Code Block
public void DisplayIsOpen()
{
    this.CurrentDisplay.GetThis().PreviewMouseWheel += 
this.
PreviewMouseWheelChanged;
}


private void PreviewMouseWheelChanged(object sender, MouseWheelEventArgs e)
{
    e.Handled = true;
    
@Info.Trace("PreviewMouseWheelChanged || Delta: " +

    if (e.Delta > 0)
;

   
//
 
If
 
the
 
mouse
 
wheel
 
delta is positive
@Display.MainPage.ZoomLevel += 0.1;
    else if (e.Delta 
>
< 0)
        @Display.MainPage.ZoomLevel -= 0.1;
}

Multiple Popups Management

Key Considerations

  • Each popup is independent instance
  • Use unique identifiers for tracking
  • Consider memory usage
  • Handle cleanup properly

Common Pattern

csharp

// Track popup instances
private List<object> openPopups = new List<object>();

public void OpenNewPopup(string data)
{
    var popup = 
@Display.
MainPage.ZoomLevel += 0.1
DetailPopup.NewPopup();
    popup.SetCustomPropertyValue("Data", data);
    openPopups.Add(popup);
}

public void 
// If the mouse wheel delta is negative?
CloseAllPopups()
{
    foreach(var popup in openPopups)
    {
        popup.Close();
    
if (e.Delta < 0
}
    openPopups.Clear();
}

See → Multiple Popups for advanced scenarios.


Code Editor Features

  • Syntax highlighting
  • IntelliSense support
  • Error checking
  • Find/Replace
  • Code folding
  • Breakpoint debugging (development mode)

See → Code Editor for complete feature documentation.


External References

For using custom DLLs and assemblies:

  • Add references via Scripts → References
  • Available to all CodeBehind
  • Shared with Script modules

See → Scripts References for configuration.


Best Practices

  1. Keep Methods Light - Avoid heavy processing in event handlers
  2. Use Async When Needed - Prevent UI blocking
  3. Clean Up Resources - Use DisplayClosing() for cleanup
  4. Cache References - Store frequently used objects
  5. Handle Errors - Try-catch in event handlers
  6. Document Code - Comment complex logic
  7. Test Performance - Monitor UI responsiveness

Common Patterns

Initialize Once

csharp

private bool initialized = false;

public void DisplayIsOpen()
{
    if (!initialized)
    {
        InitializeDisplay();
        initialized = 
@Display.MainPage.ZoomLevel -= 0.1
true;
    }
}

Periodic Updates

csharp

private DateTime lastUpdate = DateTime.MinValue;

public void DisplayIsOpen()
{
    if (DateTime.Now - lastUpdate > TimeSpan.FromSeconds(1))
    {
        UpdateDisplay();
        lastUpdate = DateTime.Now;
    }
}

Troubleshooting

Display Freezing:

  • Check for blocking code in events
  • Use async methods
  • Move heavy logic to Scripts

Methods Not Firing:

  • Verify method signatures
  • Check display is correct type (Page/Popup/Dialog)
  • Review build errors

Variable Scope Issues:

  • Use Custom Properties for persistence
  • Class-level variables for display lifetime
  • Static variables for cross-display data

In this section...

}In this section:

Page Tree
V10
rootV10:@parentspaces