LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Tree control vs. string control: "value changed" timing race?

Solved!
Go to solution

I'm developing a configuration dialog that uses a tree control and a tabbed pane and I'm having problems with the event timing. The tree control shows the structure of connected hardware and the tabbed pane shows the configuration for the selected node. The tree control is used because a tabbed pane cannot have additional tabs created during run-time, and the connected hardware varies from installation to installation. Rather than writing a hard-coded tabbed pane for every deployment, I'm using a flexible class structure that allows an "m x n" configuration--m zones with n channels per zone, but n is variable by zone. Selecting a node in the tree populates the appropriate tab with the node's values. The number of zones is limited to the number of configured system displays (discrete monitors) and the total number of channels is limited to the number of installed A/D channels. To capture the configuration data, each control in the tabbed pane has a "value changed" event, which sets the value to the appropriate element in the class.

 

Now that you know what it's supposed to do, here's the problem: it only works if you don't click the tree after changing a value. E.g. if you type in a new "scale" and then click somewhere else on the tabbed pane, the value is correctly associated with the node. If you click on a different node in the tree before exiting the field, the value is assigned to the clicked node instead. I've looked at the timestamps for the events and the field's "value changed" event fires first, so the tree's value should still be the original node. Instead, the tree seems to update before the field's "value changed" event is handled, even though the field's event was fired first. I'm reading the value of the tree inside the event handler for the field, but there's no way to get the "previous" value since the field control is in the tabbed pane.

 

So where do I go from here? Is this a legitimate race condition, or am I just not processing the events properly? I'd prefer not to post the code since it's rather cumbersome with all of its dependencies, but I can try and make a simple example.

 

configure screen cap.png

 

0 Kudos
Message 1 of 14
(4,665 Views)

I'd have to experiment, but you could try the Tree Control:Value Changed? filter event.  Just maybe that will fire after the setting's value changed event.  That will keep the Tree Control's value from changing until that filter event is performed.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 2 of 14
(4,657 Views)

It would be great if you could create a small example that shows the problem.

 

Your best bet is probably to update all not yet accepted values in a "value change event" of the tree control. I.e. if the tree control changes, you have an event terminals for "old value" which you can use to update everything before proceeding to the new item.

 

 

Message 3 of 14
(4,652 Views)

Thanks for the swift replies!

 

It looks like there isn't a filter event for Tree:Value Change. I'll look into altenbach's suggestion of adding a handler to the tree's Value Changed code for the previous value in addition to the Value Change for the fields.

 

 

0 Kudos
Message 4 of 14
(4,644 Views)
Solution
Accepted by topic author Cranky

Cranky wrote:

It looks like there isn't a filter event for Tree:Value Change.


That kind of suprises me.  But I couldn't find it either.

 

My other thought (along the lines of Altenbach's) would be to store in a shift register the currently selected item.  Since the tree's value change is happening after the setting's value change, you read the shift register value for the setting change and then update the shift register with the tree value change.  Be sure to wire the values straight though for all event cases except the Tree Value Change.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 5 of 14
(4,627 Views)

I would prefer not to wire another shift register through the main loop (already have 3: state, top-level object, error) but that may end up being the only workable solution. Another solution--though much less desirable--would be a local/global variable.

0 Kudos
Message 6 of 14
(4,619 Views)

Here's a simplified version that exhibits the same behavior.

0 Kudos
Message 7 of 14
(4,611 Views)

Here's a revision that properly tracks the old tree value and updates the array correctly but still exhibits the behavior above, i.e. the text value now ends up in both indices. There isn't a filter for the string's Value Change event either, so I'm going to have to look in to a global variable for the last node index...

0 Kudos
Message 8 of 14
(4,607 Views)

You need to follow CrossRulz's idea.

 

I wouldn't call what you have going on a race condition exactly.  Everything is happening in the exact order you'd expect.

 

When you click the off the value and onto the tree, you are nearly simultaneously firing two events.  The value change for the string control is happening first, followed immediately by the value change of the tree control.  When the value change event of the string fires, you are then in its event case reading the current value of the tree control, which happens to be the new value since the value has already changed.

Message 9 of 14
(4,604 Views)

Yes, it's not quite a race condition because it doesn't happen in a random sequence, but it completes in an unexpected (at least to me) order. I'll give the shift register idea a go and see what it does.

0 Kudos
Message 10 of 14
(4,600 Views)