# Create Customizer with Property dropdown

**URL:** <https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306>\
**Category:** Module Development\
**Tags:** ignition81, vision\
**Created:** [May 15, 2025, 3:11pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306 "2025-05-15T15:11:59Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [May 15, 2025, 3:11pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/1 "2025-05-15T15:11:59Z")

</div>

I am creating a custom vision component that pushes values into the properties of other vision components on the window. Normally to do this, I would have to set up an expression on the downstream component property to accept a value from one tag or the other, depending on a specific case. For instance, on the value of a numeric label:

```python
if (component1.enabled, {someTagName}, {otherTagName})

```

I want to build a customizer that looks like this:

| TagPath | Property |
| --- | --- |
| [default]someTagName | component1.value |

With the tag browser tree and property browser tree on the side. Then, when the 'enabled' property of the custom component is activated, push the values from the TagPath column into it's respective property via the Property Binding system. I recognize that this is something that has probably never been done before and relies on the fragile Property Binding system. However, I consider myself a pioneer and would love to attempt.

All this being said, is this something that can be done? If so, what is a good starting point and what should I watch out for? I am specifically stuck on setting up the Property Tree browser and creating a good binding.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 15, 2025, 3:33pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/2 "2025-05-15T15:33:27Z")

</div>

Bindings are designed to **pull** values into target properties, not **push** them. I think your approach is fundamentally broken. Even if you get something working, it will be utterly unintuitive to the poor designers who follow you.

Perhaps you should share more about your motivation for this approach.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [May 15, 2025, 3:47pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/3 "2025-05-15T15:47:38Z")

</div>

I phrased it poorly. You could say that I want the properties designated in the Property column to 'pull' values from the tag paths found in the TagPath column. My motivation is to minimize the workflow of setting up my custom component, as it will most likely be built into all the templates my company has developed thus far. And that alone is no small feat. I was thinking I could get something rolling with the AbstractPropertyEditorPanel class, but unsure how to implement.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 15, 2025, 4:06pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/4 "2025-05-15T16:06:31Z")

</div>

That's still "pushing" into the target properties. If you absolutely need to force tag subscriptions like this (in an SDK component), you should do them outside the binding system.

I would recommend against it entirely. You are setting yourself up for a maintenance nightmare.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [May 15, 2025, 4:09pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/5 "2025-05-15T16:09:02Z")

</div>

What do you mean outside the binding system? Do you mean by simply 'writing' a subscripted tag value into the property? What is the syntax for that? I am not bedded with the idea of using the binding system (which again, is fragile).

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 15, 2025, 4:11pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/6 "2025-05-15T16:11:48Z")

</div>

Yes, you set up a tag subscription listener on component startup, writing directly to targets as values arrive, and unsubscribe on component shutdown.

But again, I strongly recommend you **not** do this. Use ordinary bindings to supply values to your components.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [May 15, 2025, 4:13pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/7 "2025-05-15T16:13:42Z")

</div>

And if my target is a property on another component, how do I reliably allow the user to select that property from a tree (like in the expression property window)?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 15, 2025, 4:14pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/8 "2025-05-15T16:14:24Z")

</div>

Don't. Let the user be responsible for placing a binding on that other component.

Really.

Values arriving in a component's properties from an unknown source is an utter disaster for future colleagues. Don't do it.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [May 15, 2025, 4:17pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/9 "2025-05-15T16:17:00Z")

</div>

As I said, I am attempting to pioneer a new workflow for my company. I am not trying to supplant IA's initial design decisions, but augment them. That being said, is there a way to write to the property of another component?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 15, 2025, 4:28pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/10 "2025-05-15T16:28:14Z")

</div>

Sure. Call the appropriate setter method on the target component.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [May 15, 2025, 4:35pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/11 "2025-05-15T16:35:21Z")

</div>

Could I potentially use the PropertyChangeSupport class to aide in mapping tag paths to specific properties?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 15, 2025, 4:37pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/12 "2025-05-15T16:37:06Z")

</div>

No, because that is optional and is typically only used by components that are a composite of inner components. (It is only applicable to components that will **receive** values, not send them. That is, pull, not push.)

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [May 15, 2025, 4:43pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/13 "2025-05-15T16:43:39Z")

</div>

I guess I should provide a little more context. My custom component is essentially going to act as a tag value simulator, pushing values from a correspondent tagpath in a table into the property of another component. This means that the standard tag subscription and subsequent property setter method won't work.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 15, 2025, 5:01pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/14 "2025-05-15T17:01:34Z")

</div>

History playback system?

If the target properties would normally be bound to an actual tag, consider using [ClientTagManager.addClientTagProvider()](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.47/com/inductiveautomation/ignition/client/tags/model/ClientTagManager.html#addClientTagProvider(com.inductiveautomation.ignition.client.tags.model.ClientTagProvider)) to inject a proxy for gateway tag providers as desired.

The proxy would have to intelligently forward any non-relevant requests to the real gateway tag provider, and wrap any subscriptions for later redirection.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [May 15, 2025, 5:07pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/15 "2025-05-15T17:07:47Z")

</div>

So if I have a gateway tag provider named 'default' and I activate the tag injection on my custom component, I would then spoof a client tag provider (also named 'default') with copies of the exact same tags, feeding the values I have pre-created? Sounds like a good option, but I have no idea where to start. How would I set the ClientTagProvider in such a way that it takes over feeding values to the target component?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 15, 2025, 5:12pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/16 "2025-05-15T17:12:06Z")

</div>

Yes. But I've never done this. I just verified in the javadocs that this **can** work. You will have to blaze the trail.

Also note that there's no `.removeClientTagProvider()` method. You will have to keep the shim in place even when not performing substitutions.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [May 15, 2025, 5:15pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/17 "2025-05-15T17:15:59Z")

</div>

I will attempt. As long as I can 'deactivate' the ClientTagProvider when needed, this is a great solution.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [May 15, 2025, 11:01pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/18 "2025-05-15T23:01:12Z")

</div>

I am having trouble retrieving the target component by name from inside my custom component. Could you point me in the right direction? This is what I have so far, but feels very clunky:

```python
public VisionContainer getPMIRootContainer() {
        Component current = this;
        while (current.getParent() != null) {
            current = current.getParent();
        }
        if (current instanceof VisionContainer) {
            return (VisionContainer) current;
        }
        return null;
    }

    public Component getComponentFromRootByName(String name) {
        VisionContainer root = getPMIRootContainer();
        if (root != null) {
            Component component = root.getComponent(name); // Lookup by name
            if (component != null) {
                return component;
            }
        }
        return null;
    }

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 15, 2025, 11:14pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/19 "2025-05-15T23:14:04Z")

</div>

Could do something like this, to access via the same pathing we use through Ignition:

```java
    public static Component getComponentByPath(Component component, String path) {
        BindingRoot root = IgnitionSwingUtilities.getAncestorOfClass(BindingRoot.class, component);
        if (root != null) {
            return root.getComponentForPath(path);
        } else {
            return null;
        }
    }

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 16, 2025, 10:07pm UTC](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306/21 "2025-05-16T22:07:24Z")

</div>

What do you mean by "ignition properties"?

Do you want to retrieve:

1. All bean properties on the component, in a way you can loop over? Use the static methods on [`BeanInfoFactory`](https://forum.inductiveautomation.com/t/is-there-an-equivalent-of-samplequickstart-for-vision/105582/4)
2. All _custom_ properties on the component, not those that are part of the standard component (check if it's a [`DynamicPropertyProvider`](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.48/com/inductiveautomation/factorypmi/application/binding/DynamicPropertyProvider.html))
3. Or just specific custom properties by name?

[Next page](https://forum.inductiveautomation.com/t/create-customizer-with-property-dropdown/106306.md?page=2)
