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.
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:
| Method | Triggered When | Purpose |
|---|---|---|
| DisplayOpening() | Display starts opening | Initialize variables, setup |
| DisplayIsOpen() | While display remains open | Continuous updates, monitoring |
| DisplayClosing() | Display starts closing | Cleanup, 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
- Use Async Functions
csharp
public async void DisplayOpening()
{
await Task.Run(() => LongRunningOperation());
}- Offload to Scripts
- Use Script Tasks for heavy processing
- Run on server or background thread
- Prevents UI freezing
- 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:
| Method | Auto-Updates on Rename | Usage |
|---|---|---|
@Display.PageName.Open() | Yes | Preferred for pages |
@Display.PageName.NewPopup() | Yes | Create popup instance |
@Client.OpenDisplay("PageName") | No | String-based navigation |
@Client.NewPopup("PageName") | No | String-based popup |
Mouse Wheel Example
csharp
public void DisplayIsOpen()
{
this.CurrentDisplay.GetThis().PreviewMouseWheel += PreviewMouseWheelChanged;
}
private void PreviewMouseWheelChanged(object sender, MouseWheelEventArgs e)
{
e.Handled = true;
if (e.Delta > 0)
@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.DetailPopup.NewPopup();
popup.SetCustomPropertyValue("Data", data);
openPopups.Add(popup);
}
public void CloseAllPopups()
{
foreach(var popup in openPopups)
{
popup.Close();
}
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
- Keep Methods Light - Avoid heavy processing in event handlers
- Use Async When Needed - Prevent UI blocking
- Clean Up Resources - Use DisplayClosing() for cleanup
- Cache References - Store frequently used objects
- Handle Errors - Try-catch in event handlers
- Document Code - Comment complex logic
- Test Performance - Monitor UI responsiveness
Common Patterns
Initialize Once
csharp
private bool initialized = false;
public void DisplayIsOpen()
{
if (!initialized)
{
InitializeDisplay();
initialized = 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...