For decades, Goto has been treated as a programming faux pas—something to avoid at all costs. Like most rules though, there are exceptions. The Goto I’m talking about here is one of them… and it can quite literally light your app on fire—programmatically speaking.
One of the hidden gems in Xojo 2025r3 is support for XAML transitions, which makes it possible to add lightweight animations to your UI without writing any custom animation code in Xojo. Instead, you define visual states in XAML and let the XAML engine handle the animation for you.
At a high level, the workflow looks like this:
- Define one or more VisualStates in XAML.
- Attach transitions to those states (for example, moving or fading an element).
- From Xojo code, switch between states using
Invoke("GotoState", ...).
💡 Pro TipDesktopXAMLContainer subscribes to Operator_Lookup, so you don’t have to call Invoke directly. Instead of writing XAMLContainer1.Invoke("GotoState", "WhichState"), you can simply call XAMLContainer1.GotoState("WhichState").
Visual States in XAML
A VisualState represents a named configuration of UI properties. When you transition from one state to another, XAML can automatically animate the change.
Below is a simple example that animates a fire emoji 🔥 moving upward, similar to a candle flame flickering or burning upward.
Example XAML
This example uses a TextBlock to display the fire emoji and animates its vertical position with a TranslateTransform. Note that visual states must be defined on a control, so we attach them to a UserControl, allowing it to participate in GotoState transitions.
<UserControl>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="FlameStates">
<VisualState Name="Bottom">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="FlameTransform"
Storyboard.TargetProperty="Y"
To="40"
Duration="0:0:1" />
</Storyboard>
</VisualState>
<VisualState Name="Top">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="FlameTransform"
Storyboard.TargetProperty="Y"
To="-100"
Duration="0:0:1" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBlock
Text="🔥"
FontSize="32"
HorizontalAlignment="Center"
VerticalAlignment="Bottom">
<TextBlock.RenderTransform>
<TranslateTransform Name="FlameTransform" />
</TextBlock.RenderTransform>
</TextBlock>
</Grid>
</UserControl>
In this XAML:
- The
VisualStateGroupnamed FlameStates contains two states:- Bottom – moves the emoji downward.
- Top – moves the emoji upward.
- The
DoubleAnimationtargets theYproperty of aTranslateTransform. - The transition duration is handled entirely by XAML.
Triggering the Transition from Xojo
Once the visual states are defined, switching between them from Xojo is straightforward. Assuming this XAML is hosted in a XAMLContainer named XAMLContainer1, you can trigger the animation like this:
XAMLContainer1.GotoState("Top")
And to move it back down:
XAMLContainer1.GotoState("Bottom")
Why This Is Powerful
What makes this feature especially useful is that:
- The animation logic stays in XAML, where it naturally belongs.
- Xojo code remains clean and declarative—just tell the UI which state to go to.
- More complex effects (opacity, scaling, rotation, easing functions) can be added without changing any Xojo code.
Here’s a more interesting variation, where the flames drift upward rather than moving in a straight line:
<UserControl>
<Grid Width="160" Height="240">
<!-- Fire emoji 1 -->
<TextBlock Name="Fire1"
Text="🔥"
FontSize="32"
VerticalAlignment="Bottom"
HorizontalAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform Name="Move1"/>
</TextBlock.RenderTransform>
</TextBlock>
<!-- Fire emoji 2 -->
<TextBlock Name="Fire2"
Text="🔥"
FontSize="26"
VerticalAlignment="Bottom"
HorizontalAlignment="Center"
Margin="20,0,0,0"
Opacity="0.8">
<TextBlock.RenderTransform>
<TranslateTransform Name="Move2"/>
</TextBlock.RenderTransform>
</TextBlock>
<!-- Fire emoji 3 -->
<TextBlock Name="Fire3"
Text="🔥"
FontSize="22"
VerticalAlignment="Bottom"
HorizontalAlignment="Center"
Margin="-20,0,0,0"
Opacity="0.7">
<TextBlock.RenderTransform>
<TranslateTransform Name="Move3"/>
</TextBlock.RenderTransform>
</TextBlock>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="FireStates">
<VisualState Name="Off"/>
<VisualState Name="On">
<Storyboard RepeatBehavior="Forever">
<!-- Fire 1 -->
<DoubleAnimation Storyboard.TargetName="Move1"
Storyboard.TargetProperty="Y"
From="0"
To="-180"
Duration="0:0:1.2"/>
<DoubleAnimation Storyboard.TargetName="Move1"
Storyboard.TargetProperty="X"
From="0"
To="10"
Duration="0:0:0.6"
AutoReverse="True"/>
<!-- Fire 2 -->
<DoubleAnimation Storyboard.TargetName="Move2"
Storyboard.TargetProperty="Y"
From="0"
To="-160"
Duration="0:0:1.0"
BeginTime="0:0:0.3"/>
<DoubleAnimation Storyboard.TargetName="Move2"
Storyboard.TargetProperty="X"
From="0"
To="-12"
Duration="0:0:0.5"
AutoReverse="True"/>
<!-- Fire 3 -->
<DoubleAnimation Storyboard.TargetName="Move3"
Storyboard.TargetProperty="Y"
From="0"
To="-140"
Duration="0:0:1.4"
BeginTime="0:0:0.15"/>
<DoubleAnimation Storyboard.TargetName="Move3"
Storyboard.TargetProperty="X"
From="0"
To="8"
Duration="0:0:0.7"
AutoReverse="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</UserControl>
To light up the flames we’ll simply invoke the “On” state:
XAMLContainer1.GotoState("On")
For subtle UI polish—like animated indicators, highlights, or playful effects such as this candle flame—XAML transitions provide a surprisingly powerful new tool in Xojo.
William Yu grew up in Canada learning to program BASIC on a Vic-20. He is Xojo’s resident Windows and Linux engineer, among his many other skills. Some may say he has joined the dark side here in the USA, but he will always be a Canadian at heart.
