Understanding the concept of WhileTrue

I have problem understanding the working logic of WhileTrue. Please check the example below.

<App Theme="Basic">

    <Grid Rows="1*, 50">

        <Panel>

            <Panel>
                <WhileTrue ux:Name="t_flag">
                    <Rectangle Width="50" Height="50" Fill="#F00" />
                </WhileTrue>
            </Panel>

            <!-- this one failed to display, why? -->
            <WhileTrue ux:Name="t_flag">
                <Rectangle Width="50" Height="100" Fill="#0F0" />
            </WhileTrue>

            <Rectangle Width="50" Height="150" Fill="#000" />

        </Panel>

        <Button Text="Toggle flag">
            <WhilePressed>
                <Change t_flag.Value="true" />
            </WhilePressed>
        </Button>

    </Grid>

</App>

ux:Name assigns names to the objects, it does not create a logical name for the condition. Consider that each ux:Name is essentially a variable declaration, so in the above you’ve basically done something like this:

var t_flag = new WhileTrue();
var t_flag = new WhileTrue();

You have two variables with the same name (we should probably emit an error for this, I’ll raise an issue).

The WhilePressed trigger is thus only setting the value of one of them.

Sorry for the problem in my sample app. But even if you separate that to 2 names, it is still not working.

<App Theme="Basic">

    <Grid Rows="1*, 50">

        <Panel>

            <Panel>
                <WhileTrue ux:Name="t_flag">
                    <Rectangle Width="50" Height="50" Fill="#F00" />
                </WhileTrue>
            </Panel>

            <!-- this one failed to display -->
            <WhileTrue ux:Name="t_flag_2">
                <Rectangle Width="50" Height="100" Fill="#0F0" />
            </WhileTrue>

            <Rectangle Width="50" Height="150" Fill="#000" />

        </Panel>

        <Button Text="Toggle flag">
            <WhilePressed>
                <Change t_flag.Value="true" />
                <Change t_flag_2.Value="true" />
            </WhilePressed>
        </Button>

    </Grid>

</App>

This example does infact work, but the problem is with the layout of the UX. It will render correctly if you remove the WhileTrue, but it’s still kind of strange, with the panels inside panels.

Sometimes you would like some UI to hidden until a condition happens, so I believe using WhileTrue is one of the way to achieve this. Using Visibility="Collapsed" will work too, but I am not sure about how Fuse manage the memory. It seems that using WhileTrue controls whether an item is added / not added into the layout, probably better than just controlling visibilility.

Only Panel inside Panel works seems odd, but if you check out their examples, they are implementing something similar. That is why I am interested to know how WhileTrue actually works. Looks like WhileTrue have to be inside it’s own dedicated Panel.

This is the loading button example by them.

  <Panel>
    <WhileTrue ux:Name="showCross" Opacity="0">
      <CrossIcon ux:Name="crossIcon"/>
      <Change crossIcon.Opacity="1" Duration="0.05"/>
    </WhileTrue>
  </Panel>
  <Panel>
    <WhileTrue ux:Name="showCheck">
      <CheckIcon ux:Name="checkIcon" Opacity="0"/>
      <Change checkIcon.Opacity="1" Duration="0.05"/>
    </WhileTrue>
  </Panel>

It’s correct that your second Rectnagle is not displaying due to layout, but it’s not obvious why. WhileTrue is a Behavior. When it contains nodes it simply adds those nodes to the end of the child list. This means your second rectangle will be behind the large one and thus never seen.

You have to wrap it in a Panel to guarantee it’s position now.

We have a pending feature request that will allow better control over where behaviors insert their nodes. “Simply at the end” is not always the correct thing to do.

Thumbs up! edA-qa mort-ora-y. (It’s difficult to type the name :p)

adds those nodes to the end of the child list

That clearly explains why the layout issue happened in my sample app as well as my core project.

Can someone please show me how to get the two WhileTrue’s to use the same variable. Is that possible without using Observables?

<WhileTrue ux:Name="flag">
  <DebugAction Message="1"/>
</WhileTrue>
<WhileTrue Source="flag">
  <DebugAction Message="2" />
</WhileTrue>