Calculate rendered height using expressions and store it

I am trying to generate each items height and store it. Is that possible using expressions?

When writing this the height to a text output in UX it only runs the expression once the height is changed.

<Text Value="{= height(imageAndContent)}" />

Is there a way to run the expression when rendered, and if so then store it to an observable?

In theory that might work, but it’s kind of indirect. You can instead use the Placed event, like Placed="{onPlaced}" on the nodes.

https://www.fusetools.com/docs/fuse/elements/element/placed

But as noted on that page, we really discourage using this. What use-case are you tring to implement?

I’m trying to make this https://www.fusetools.com/examples/material-transition but with variable card height - not static as in the sample.

Once I remove the card to a new layout master outside the list I expand it to contain a long list. This is reflected to the original list (original master) and the expanded card is reflected in the original list pushing elements far down.

That screws with animations going back and setting the card back to original master and removing the long list it contains. Both the card and the list then animates.

There shouldn’t be a need to have the cards static in height. There’s nothing fundamentally limiting such transitions to working with variable height content. I haven’t looked too closely at that example, but I hope it’s only something minor that stops it from working that way.

Attempting to do this with JS will most likely fail, due to the timings of the events.

Doing this strictly in UX isn’t easy. You may have to look at things like TransitionLayout to fake transitions between unrelated elements. This doesn’t involve LayoutMaster and is quite flexible, albeit not easy to setup.

Well I actually got working with a combination of UX and Javascript using Placed.

I do this:

<Panel ux:Name="contentLimitPanel" MinHeight="460" Height="{cardHeight}" Placed="{onPlaced}">

Then in Javascript I do this:

function onPlaced(e) { if(e.data.cardHeight.value === undefined) { e.data.cardHeight.value = e.height; } }

Where the e.data.cardHeight is an Observable for each card.

The timing works because I just let it render, then placed is called and I can save the rendered cardHeight. Then the height is static from that point on.

onPlaced can be called multiple times, and might have different sizes, if the content changes of the user rotates the screen, opens the keyboard, navigates, etc. It could in theory work, but I just don’t like thinking about the possible situations where the size changes or some JS<<->Uno message is delayed. Nothing will fail terribly, but it might result in flicker as an element flips between two sizes.

The ImageView sample does full-screen transitions from arbitrary element sizes. https://github.com/fusetools/fuse-samples/tree/master/Samples/ImageViewer