How to increment progress bar through XAML animation? - c#

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>

Related

StatusBar text fade-out when binding using Caliburn.Micro

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>

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.

Problems hiding WPF StackPanel (not expander)

I have a real trouble with WPF StackPanel - I need to make it animated not only for scrolling its content horizontaly (this is ok more or less), but also I must make it expand/collapse (animated) by pressing some button on the containing window.
I have tried a lot of animated expander controls (for example http://www.codeproject.com/KB/WPF/AnimatingExpander.aspx) but they have overloaded with functionality (and some artifacts with contained controls) and not suitable for my task.
So the question is how to make SIMPLE horizontal oriented StackPanel to expand/collapse with animation by button click?
The simplest approach is to start an animation on a ToggleButton.Checked or .Unchecked event:
<StackPanel x:Name="MyStackPanel">...</StackPanel>
...
<ToggleButton Content="Click Me">
<ToggleButton.Triggers>
<EventTrigger RoutedEvent="ToggleButton.Checked">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MyStackPanel"
Storyboard.TargetProperty="Width"
To="0"
Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="ToggleButton.Unchecked">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MyStackPanel"
Storyboard.TargetProperty="Width"
To="200"
Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ToggleButton.Triggers>
</ToggleButton>
Why not adding a storyboard and double animation for stackpanel's width. By clicking the button you can start the animation in code or by defining event triggers.

Categories

Resources