StatusBar text fade-out when binding using Caliburn.Micro - c#

In my ShellViewModel I have the following property:
private string _status = "";
public string Status
{
get
{
return _status;
}
set
{
_status = value;
NotifyOfPropertyChange(() => Status);
}
}
In the ShellView I've named my StatusBar TextBlock "Status" so that it binds to the above using Caliburn.Micro - and it does.
Then I've tried to add a "StoryBoard" element so that after a short amount of time the text fades away - currently the text appears but does not fade away - how do I fix this?
<StatusBar DockPanel.Dock="Bottom">
<TextBlock x:Name="Status">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="0:0:0"
To="1.0" />
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="0:0:2"
From="1.0"
To="0.0"
BeginTime="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</StatusBar>

You would need two changes,
First, you need to update the binding to Raise the TargetUpdated Event when property changes. This can be done using Binding.NotifyOnTargetUpdated
<TextBlock Text="{Binding Status, NotifyOnTargetUpdated=True}">
Then, your BeginTime is higher than the Duration in the second animation (BeginTime="0:0:5" ), which needs to be corrected.
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="0:0:2" From="1.0" To="0.0" BeginTime="0:0:0.5" />
Complete Code
<TextBlock Text="{Binding Status, NotifyOnTargetUpdated=True}">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="0:0:0" To="1.0" BeginTime="0:0:0.5"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="0:0:2" From="1.0" To="0.0" BeginTime="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>

Related

First WPF animation then run the code in Screen ViewModel

Hello I have a question I want to do this animation then when the animation is completed I would like to run the code and I can't figure it out the way to do it in MVVM using CaliburnMicro.
Please help me if possible.
<Button x:Name="Forgot">
<Button.RenderTransform>
<TranslateTransform />
</Button.RenderTransform>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="UserName"
Storyboard.TargetProperty="RenderTransform.(TranslateTransform.X)"
From="0" To="-1000" Duration="0:0:1" />
<DoubleAnimation Storyboard.TargetName="Password"
Storyboard.TargetProperty="RenderTransform.(TranslateTransform.X)"
From="0" To="-1000" Duration="0:0:1" />
<DoubleAnimation Storyboard.TargetName="LogIn"
Storyboard.TargetProperty="RenderTransform.(TranslateTransform.X)"
From="0" To="-1000" Duration="0:0:1" />
<DoubleAnimation Storyboard.TargetName="Forgot"
Storyboard.TargetProperty="RenderTransform.(TranslateTransform.X)"
From="0" To="-1000" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
You should listen to the Completed event a StoryBoard raises once the animations finishes.
You can either use an EventTrigger for that (though I am not certain if that will work) or bind a handler in XAML and do whatever you like at that point.
Update:
XAML:
<Storyboard Completed="storyboard_Completed">
...
C#:
void storyboard_Completed(object sender, EventArgs args)
{
// Do whatever you want here.
}
I did it like this.
private void DoubleAnimation_Completed(object sender, EventArgs e)
{
LoginViewModel vm = this.DataContext as LoginViewModel;
vm.Forgot();
}
and now it works. thank you

How to increment progress bar through XAML animation?

I need to place a progress bar that takes 10 seconds to complete 100% progress. It should increment 10% per second. I would like a XAML approach. I know how to do that with a DispacherTimer or similar thing. How can I do that with XAML only?
I have some idea, but I don't know how to finish it or even if it's possible.
<ProgressBar>
<ProgressBar.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<DoubleAnimation From="0" To="100" Duration="0:0:10"></DoubleAnimation>
</BeginStoryboard>
</EventTrigger>
</ProgressBar.Triggers>
</ProgressBar>
How about simply using a DoubleAnimation that animates the Value property using linear interpolation over 10 seconds?:
<ProgressBar Minimum="0" Maximum="100">
<ProgressBar.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="0" To="100" Storyboard.TargetProperty="Value" Duration="00:00:10" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ProgressBar.Triggers>
</ProgressBar>

Need help applying animation in transform group in wpf

I have a piece of xaml that applies a scale transform and a rotatetransform.
<Image.RenderTransform>
<TransformGroup>
<RotateTransform Angle="0" x:Name="RotateTransform"/>
<TranslateTransform X="0" Y="0"/>
<ScaleTransform ScaleX="2" ScaleY="2"/>
</TransformGroup>
</Image.RenderTransform>
I also have a storyboard that needs to accesss RotateTransform like so:
<Storyboard x:Key="Storyboard"
Storyboard.TargetProperty="(RenderTransform).(RotateTransform.Angle)"
Storyboard.TargetName="RotateTransform">
<DoubleAnimation From="0" To="360" RepeatBehavior="Forever" SpeedRatio="0.25" />
</Storyboard>
However I can not get the image to rotate, but it does scale up. Does anyone have suggestions to fix the problem?
Edit: I did figure out that i can use
<Storyboard x:Key="Storyboard"
Storyboard.TargetProperty="(Image.RenderTransform).Children[0].Angle"
Storyboard.TargetName="ContentImage">
<DoubleAnimation From="0" To="360" RepeatBehavior="Forever" SpeedRatio="0.25" />
</Storyboard>
And call the animation by the array position, but why is it not possible to actually call the transform property's angle property automatically by x:Name?
A RotateTransform does not have RenderTransform property, so you can't animate RenderTransform.Angle.
The animation would have to target the Angle property directly. Moreover, you would usually apply the TargetName and TargetProperty properties to the DoubleAnimation, not to the Storyboard. You would also set the Duration of the animation instead of applying a SpeedRatio for the default duration of one second.
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="RotateTransform"
Storyboard.TargetProperty="Angle"
From="0" To="360" RepeatBehavior="Forever" Duration="0:0:4"/>
</Storyboard>
The RenderTransform and RotateTransform are associated properties and need parenthesis around them. This is the correct syntax.
<Storyboard x:Key="Storyboard"
TargetProperty="(RenderTransform).Children[0].(RotateTransform.Angle)"
TargetName="ContentImage">
<DoubleAnimation From="0" To="360" RepeatBehavior="Forever" SpeedRatio="0.25" />
</Storyboard>
as you pointed out in your edit you could also write this as
<Storyboard x:Key="Storyboard"
TargetProperty="(RenderTransform).Children[0].Angle"
TargetName="ContentImage">
<DoubleAnimation From="0" To="360" RepeatBehavior="Forever" SpeedRatio="0.25" />
</Storyboard>

Image fade doubleanimation

I'm trying to achive a fade out effect on an image in wpf and c#
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="imgSlot1"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
With this code i see my image flashing,and that's ok but why if i change RepeatBehavior to "1x" or "0:0:1" and AutoReverse to "False" (i have to create a single effet of fade out on my image) nothing works?
I was a bit surprised when you said nothing works when you set AutoReverse="False" and RepeatBehavior="1x", so I tried it, and a single fade out works fine. Here is the xaml:
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="imgSlot1"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1"
AutoReverse="False" RepeatBehavior="1x"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
However, I am not sure you want that to occur on the Image.Loaded event. And remember you can easily control that from C# or VB, even without a storyboard, similar to the following:
DoubleAnimation fadeoutAnimation = new DoubleAnimation();
fadeoutAnimation.Duration = TimeSpan.FromSeconds(1.0d);
fadeoutAnimation.From = 1.0d;
fadeoutAnimation.To = 0.0d;
imgSlot1.BeginAnimation(Image.OpacityProperty, fadeoutAnimation);
Hope this helps!

Storyboard DoubleAnimation Does not work with StackPanel Height Property

I'm trying to use DoubleAnimation to change the Height property of a StackPanel. The code does not throw any exception. But the animation does not work.
<StackPanel x:Name="FlyoutContent">
<StackPanel.Resources>
<Storyboard x:Name="HideStackPanel">
<DoubleAnimation Storyboard.TargetName="ChangePasswordPanel" Storyboard.TargetProperty="Height" From="190" To="0" Duration="0:0:1">
<DoubleAnimation.EasingFunction>
<PowerEase EasingMode="EaseIn"></PowerEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
<Storyboard x:Name="ShowStackPanel">
<DoubleAnimation Storyboard.TargetName="ChangePasswordPanel" Storyboard.TargetProperty="Height" From="0" To="190" Duration="0:0:1">
<DoubleAnimation.EasingFunction>
<PowerEase EasingMode="EaseIn"></PowerEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</StackPanel.Resources>
<TextBlock Margin="0, 20, 0, 0" FontWeight="Bold" Text="Change Current Password" TextWrapping="Wrap" Style="{StaticResource BasicTextStyle}" HorizontalAlignment="Left" IsTapEnabled="True" Tapped="ChangePasswordHeader_Tapped"/>
<StackPanel x:Name="ChangePasswordPanel" Margin="0, 5, 0, 0" Height="0">
C# Event Handler
private void ChangePasswordHeader_Tapped(object sender, TappedRoutedEventArgs e)
{
if (ChangePasswordPanel.Height == 0)
{
ShowStackPanel.Begin();
}
else
{
HideStackPanel.Begin();
}
}
It does hit ChangePasswordHeader_Tapped event handler and execute ShowStackPanel.Begin or HideStackPanel.Begin statement as expected. But it does not have any impact on the output. The Height of the StackPanel just stays at 0.
Any idea on what's happening??
I figured it out myself. All I had to do was to Enable Dependent Animation (EnableDependentAnimation) on the DoubleAnimation as this animation affects the layout. And then it worked perfectly.
<Storyboard x:Name="HideChangePasswordPanel">
<DoubleAnimation EnableDependentAnimation="True" Storyboard.TargetName="ChangePasswordPanel" Storyboard.TargetProperty="Height" From="190" To="0" Duration="0:0:0.2">
<DoubleAnimation.EasingFunction>
<PowerEase EasingMode="EaseIn"></PowerEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
<Storyboard x:Name="ShowChangePasswordPanel">
<DoubleAnimation EnableDependentAnimation="True" Storyboard.TargetName="ChangePasswordPanel" Storyboard.TargetProperty="Height" From="0" To="190" Duration="0:0:0.2">
<DoubleAnimation.EasingFunction>
<PowerEase EasingMode="EaseIn"></PowerEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
Hope it saves someone some time!
The easiest way to animate the size of a UI component generally in XAML (and Silverlight/WPF) is to use a RenderTransform. Depending on the layout, you may need to do a few tricks, but for a quick animation, it generally looks very nice.
<Storyboard x:Name="Storyboard1">
<DoubleAnimation Duration="0:0:2"
To="0"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)"
Storyboard.TargetName="StatListView" d:IsOptimized="True"/>
<DoubleAnimation Duration="0:0:2"
To="0"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="StatListView" d:IsOptimized="True"/>
</Storyboard>
The stack panel takes its height from the combined height of its contents. Setting the height explicitly has no meaning.
You need to change the height/visibility of the stack panel's contents.

Categories

Resources