I played around with a semaphore approach for a while and gave up. I switched to an approach where I wrote an action engine for property changes, where the property change was accomplished by, in a loop, writing and reading the property until I could detect a change. I still experienced problems with this, so I finally gave up and just changed my control property to the entire Display State cluster. This way, I can just call the property node once with everything I want to change (it seems like the problems come from multiple property node calls that run so quickly that some display state information is lost when some/most cases don't get executed in the xcontrol). This technique sort of works, but there is still a problem preventing the property node from executing before the xcontrol has had an opportunity to run the data change case. It matters in my case because I am trying to set plot names, and it doesn't work if there isn't data in the graph yet to support the number of plots. Data flow is broken, that is, you can not guarantee the order of execution by controlling the order that your elements (property nodes, terminals) are executed.
Two things would probably make this better for me: 1) a major overhaul of xControls to fix these race conditions, or 2) the abilty to inherit functionality from the elements of the xControl (I have a graph control in my xControl, I'd like to inherit the properties of the graph control so I don't have to add each one individually--and not have them work correctly anyway).
I've pretty much decided to scrap the xControl, and just transition all the code to the actual vi it's being used in. It will be messy, but at least I can guarantee that it will work correctly. I don't know if this helped you at all, but at least it documents my troubles.
As an aside, it appears that in 8.2.1 the problem still exists that an ActiveX container can't be hidden on a tab page when that page is not in front; at least, when that activeX container is part of an xControl.