Accessing Multi-Component Controls and Subscribing to Internal Events

Note: The content of this page is for Screens only and does not apply to Pages.
In Wise SCADA, objects do not always consist of a single, simple component. For example, objects such as a Recipe Manager, Alarm View, and similar elements are multi-component objects that contain sub-objects like Buttons, ComboBoxes, ScrollBars, and TextBoxes within them.

In standard usage, we manage the properties of these main objects from the Properties panel. However, sometimes you may need a much more specific scenario: What if we want to intervene in the event of a specific sub-object within this main object (for example, when the “Load” button inside the Recipe Manager is clicked)?

This is where the flexible script architecture of Wise SCADA comes into play. Through C# scripts, you can navigate down the object hierarchy, find internal sub-controls, and listen to all actions of these objects by attaching standard event handlers.

Example Scenario: Saving the Time When a Recipe is Loaded

Let’s say we have a Recipe Manager on our screen. Our goal is to catch this action in the background the moment the operator presses its standard “Load” button, and write the system’s current time to a Tag.

To achieve this, we need to connect to the system’s object tree using the page’s Screen_Load event.

Example Script

C#
using System;
using System.IO;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using Microsoft.CSharp;

public class MainClass
{
    public void Main()
    {
    }

    public void Screen_Load(Object sender, EventArgs e)
    {
        // Getting the current screen (form) as a reference
        Form form = sender as Form;

        // Searching for the main object named "RecipeManager_0" on the form
        Control[] recipes = form.Controls.Find("RecipeManager_0", true);

        // Searching for the sub-object named "LoadButton" inside the found main object (RecipeManager_0)
        Control[] buttons = recipes[0].Controls.Find("LoadButton", true);

        // Subscribing our custom function written below to the MouseDown event
        buttons[0].MouseDown += LoadButton_MouseDown;
    }

    // Our function that will be triggered by the MouseDown event
    public void LoadButton_MouseDown(Object sender, MouseEventArgs e)
    {
        TagSet("_Tag", DATETIME.Now); 
    }
}
Tip: How Do I Find the Names of Sub-Objects?

You might ask, “How will I know that the button inside the Recipe Manager is named LoadButton?” To discover the internal structure of complex objects and the names of the sub-controls they contain, you can write a recursive function to print the entire object tree to the screen.

During the testing phase, if you add the following discovery function to your script and call it by passing your main form from within Screen_Load, you can see the names (Name) and types (Type) of all hidden controls in the system as a list:

C#
// The recursive function we created to scan the object tree in depth
public void ShowControls(Control parent, string indent)
{
    // Loops through all sub-objects inside the specified main object (parent) in sequence
    foreach (Control control in parent.Controls)
    {
        // Displays the name (Name) and type (Type) of the found sub-object on the screen as a message box
        MessageBox.Show(
            indent + "Name: " + control.Name +
            "\nType: " + control.GetType().FullName);
        
        // If there are other objects inside this sub-object, the function calls itself again to find them
        ShowControls(control, indent + "  ");
    }
}

Thanks to this discovery method, you can access hidden TextBoxes, ScrollBars, or Buttons not only inside the Recipe Manager, but also within the User Manager, Alarm View, or complex graphic components, and assign custom functions to them.

Note: This discovery function scans all objects and their sub-components on the form and generates a separate MessageBox for each one. When run on a crowded screen with a large number of objects, you may encounter dozens of message boxes that keep popping up one after another. Therefore, it is recommended to perform your sub-object name detection operations not on the main screens of your project, but only on a simple test page that contains the relevant object.

Similar Posts

Leave a Reply