Reputation: 43
I am attempting to migrate my wpf application over to avalonia UI. Some aspects seem pretty confusing or scattered all over.
I have simple Image object in my wpf xaml:
<Image.Style>
<Style TargetType="Image">
<Setter Property="Opacity" Value="0" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsBusy}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource fadeInAnimation}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource fadeOutAnimation}" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
It is nicely bound with boolean IsBusy property that sits in my Datacontext. Changing the value of the property launches smooth transition of the opacity and sets the Visibility appropriataly.
<Storyboard x:Key="fadeOutAnimation">
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="1" To="0"
Duration="0:0:0.3"/>
<ObjectAnimationUsingKeyFrames BeginTime="0:0:0.3"
Storyboard.TargetProperty="Visibility"
Duration="0:0:0">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
I like to keep the xaml and viewmodel totally separated. No code behind at all.
The documentation provided on the Avalonia UI is really rudimentary. I can only find information about transiotions and animations, though no mention of triggering visual actions by changeds of bound properties.
There is also Avalonia.Xaml.Behaviors and its DataTriggerBehavior but the only example shows how to change the colour of the control. I can't connect the dots.
Are there any better resources on how to dive deep into the Acalonia UI?
Ta
Upvotes: 4
Views: 2055
Reputation: 2675
In order to trigger animation on an object based on a ViewModel property, you will have to define a Style Class on the object that is bound to that property. Once this is done you can apply your KeyFrame Animation to that Style Class through a selector. Consider the following example:
<StackPanel Orientation="Horizontal">
<Border Classes.triggered="{Binding AnimationOn}" Background="Red" Width="100" Height="100" >
<Border.Styles>
<Style Selector="Border.triggered">
<Style.Animations>
<Animation Duration="0:0:3" IterationCount="INFINITE">
<KeyFrame Cue="0%">
<Setter Property="Opacity" Value="0.0"/>
</KeyFrame>
<KeyFrame Cue="50%">
<Setter Property="Opacity" Value="1.0"/>
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Opacity" Value="0.0"/>
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Border.Styles>
</Border>
<ToggleButton IsChecked="{Binding AnimationOn}" Width="100" Height="35" Content="Animate It!"/>
</StackPanel>
If you want a more toggle-able effect rather than a repeating effect, you can do the same with Transitions. In this case however, you don't apply the transition in the style, you set the transition on the control and then you just change the Opacity property.
<StackPanel Orientation="Horizontal">
<Border Classes.triggered="{Binding AnimationOn}" Background="Red" Width="100" Height="100">
<Border.Transitions>
<Transitions>
<DoubleTransition Property="Opacity" Duration="0:0:3"/>
</Transitions>
</Border.Transitions>
<Border.Styles>
<Style Selector="Border.triggered">
<Setter Property="Opacity" Value="0"/>
</Style>
</Border.Styles>
</Border>
<ToggleButton IsChecked="{Binding AnimationOn}" Width="100" Height="35" Content="Animate It!"/>
</StackPanel>
I looked for a way to do the Collapsing. Unfortunately there is nothing extremely convenient to do this. However, you could make a custom ValueConverter that converts 0 Opacity to false (everything else to true) and then bind IsVisible directly to Opacity using that converter. Remember that Visiblity in Avalonia is a 2 state, not a 3 state like WPF (there is no Hidden state, you just set Opacity to 0 instead).
Upvotes: 4