Dynamically changing Custom Properties in a Template Canvas

Here’s a breakdown of what I have and what I’m trying to do:

Ignition version: 8.1. Module: Vision

  • RootContainer (with ExpressionBinding)
    • TemplateCanvas
      • Template (w/ CustomProperty)
        • Container
          • TextField (w/ PropertyChange script)

I have a TemplateCanvas with a Template that has a TextField. On that TextField, I have PropertyChange event script that I’m trying to use to update my CustomProperty on the Template.

Here’s the relevant portion of my script so far:

if event.propertyName == 'text':
	event.source.parent.parent.CustomProperty = "CustomProperty: " + event.newValue.strip()

No matter what I’ve tried, the CustomProperty doesn’t get changed in the Templates dataset on the TemplateCanvas when the event is triggered. I can print event.source.parent.parent.CustomProperty right after updating its value and the print statement correctly reflects the update, but the CustomProperty in the Templates dataset doesn’t.

To further complicate things, I pull multiple of these CustomProperties and concatenate them in an ExpressionBinding to build a SQL query. For that ExpressionBinding, I’m using jsonGet to interpret the Parameters from the Templates dataset on the TemplateCanvas. But without the PropertyChange updating the dataset, I’m getting nowhere.

I’ve also tried tackling the problem by changing the ExpressionBinding, but I can’t seem to access the CustomProperty on the Template within the Canvas, only through the Parameters column in the Templates dataset. (See below for my expression binding.)

jsonGet({RootContainer.TemplateCanvas.templates}[0,"parameters"],"CustomProperty") + ' ' + jsonGet({RootContainer.TemplateCanvas.templates}[1,"parameters"],"CustomProperty")

What’s the solution here? Is there a way to use a PropertyChange script to update a CustomProperty in the Parameters of a TemplateCanvas? Or is there another way to access the CustomProperty on the TemplateInstance without going through the Parameters in the Templates dataset?

I imagine that your custom property on the template is being changed by your script, but the canvas's templates dataset is used to create the templates, so modifying it will cause all the templates being rendered by the canvas to be destroyed and recreated. For this reason, it will not auto update when the initial properties of the rendered templates change. This dataset certainly can be modified by an internal template, but I doubt that's what you want.

Example:

if event.propertyName == 'text':
	# Modifies parent template canvas's dataset to set a new custom property value for a rendered template
	from javax.swing import SwingUtilities
	from com.inductiveautomation.factorypmi.application.components import TemplateCanvas
	
	template = event.source.parent.parent
	canvas = SwingUtilities.getAncestorOfClass(TemplateCanvas, event.source)
	dataset = canvas.templates
	for row in xrange(dataset.rowCount):
		if dataset.getValueAt(row, 'name') == template.name:
			canvas.templates = system.dataset.setValue(dataset, row, 'parameters', {'CustomProperty': event.newValue.strip()})
			break

If you are needing something to happen using the new text value in the window when the text field changes, consider adding a custom method to the root container and calling it from the template's propertyChange event

Example:

From the template's 'text' property change event:

if event.propertyName == 'text':
	system.gui.getParentWindow(event).rootContainer.textChangeCustomMethod(event.newValue)

Result:
image

Console output:

A text change happened!
test