I'm trying to animate a canvas in WPF using Storyboard and DoubleAnimationsUsingKeyFrames my code goes something like this:
<Canvas x:Name="bgCanvas" Height="261" Canvas.Top="-262" Width="720">
<Canvas.Background>
<ImageBrush ImageSource="Resources/backgroundBlurred.png" Stretch="UniformToFill"/>
</Canvas.Background>
<Canvas.Resources>
<Storyboard x:Key="bgAnim" x:Name="bgAnim">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(bgCanvas.Opacity)" Storyboard.Target="bgCanvas">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
<EasingDoubleKeyFrame KeyTime="1.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Canvas.Resources>
I'm also using Mahapps.Metro for the project. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(bgCanvas.Opacity)" Storyboard.Target="bgCanvas"> is underlined by blue lines and the error reads:
bgCanvas is not supported in a Windows Presentation Format (WPF) Application.
I'm not sure whats wrong with the code.
BONUS: Is this the right way to animate a canvas in WPF?
Sorry for the nub questions.
You could start the animation in an EventTrigger on the Loaded event of the Canvas:
<Canvas ...>
<Canvas.Background>
<ImageBrush .../>
</Canvas.Background>
<Canvas.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
Replace (bgCanvas.Opacity) with (Canvas.Opacity)
Related
Regarding the WPF Progress Bar when IsIndeterminate is set to true, I personally think the animation is too fast.
I think slowing the animation down and maybe making the internal bar wider would help ease this problem.
Is there anyway to customize this?
edit: added code
.xaml
<Window x:Class="IndeterminateProgressBarTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:IndeterminateProgressBarTest"
mc:Ignorable="d"
Title="MainWindow" Height="100" Width="700">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="Type">
<VisualState Name="Indeterminate">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Animation" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Animation" Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)">
<EasingPointKeyFrame KeyTime="0" Value="0,0"/>
<EasingPointKeyFrame KeyTime="0:0:0" Value="0,0"/>
<EasingPointKeyFrame KeyTime="1:0:0" Value="0,0"/>
</PointAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ProgressBar Name="progressBar" Width="600" Height="25" IsIndeterminate="True"/>
</Grid>
</Window>
.cs
namespace IndeterminateProgressBarTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
VisualStateManager.GoToElementState(progressBar, "Indeterminate", true);
}
}
}
You can customize the Indeterminate animation by editing VisualState named Indeterminate. The following is that VistalState in current default Style of ProgressBar.
<VisualState x:Name="Indeterminate">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Animation" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0" Value="0.25"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.25"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="0.25"/>
</DoubleAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Animation" Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)">
<EasingPointKeyFrame KeyTime="0" Value="-0.5,0.5"/>
<EasingPointKeyFrame KeyTime="0:0:1" Value="0.5,0.5"/>
<EasingPointKeyFrame KeyTime="0:0:2" Value="1.5,0.5"/>
</PointAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
Change 2nd and 3rd KeyTime respectively to change the speed of animation. Further customization is up to you.
Any ideas on how to flash a border but not the children inside?
I can flash the border like so:
<UserControl.Resources>
<Storyboard x:Key="valueFlasher" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="outline">
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.2"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<Border BorderBrush="Black" BorderThickness="3" CornerRadius="7" x:Name="outline">
<!--children-->
</Border>
But that will change the opacity of everything nested inside.
I was thinking something like this:
<Border BorderThickness="3" CornerRadius="7">
<Border.BorderBrush>
<SolidColorBrush Color="Black" x:Name="outline"/>
</Border.BorderBrush>
<!--children-->
</Border>
But it doesn't seem to work either. Maybe my storyboard can't find 'outline' because its nested?
Thanks in advance!
The property path (UIElement.Opacity) is not valid for SolidColorBrush, because it is not a UIElement.
Instead, use BorderBrush.Opacity
<Storyboard x:Key="valueFlasher" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="BorderBrush.Opacity"
Storyboard.TargetName="outline">
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.2"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
with a Border like this:
<Border x:Name="outline" BorderThickness="3" CornerRadius="7">
<Border.BorderBrush>
<SolidColorBrush Color="Black"/>
</Border.BorderBrush>
<!--children-->
</Border>
Or just Opacity
<Storyboard x:Key="valueFlasher" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="outline">
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.2"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
with the x:Name set on the SolidColorBrush:
<Border BorderThickness="3" CornerRadius="7">
<Border.BorderBrush>
<SolidColorBrush x:Name="outline" Color="Black"/>
</Border.BorderBrush>
<!--children-->
</Border>
I want to show a grid that involve a label and I want to show this in left-above of another grid.the wpf code(xml) is this :
<Grid.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" >
<SplineDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
<SplineDoubleKeyFrame KeyTime="0:0:5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Grid.RenderTransform>
<ScaleTransform ScaleY="1" />
</Grid>
How to create this notification when press a button?
I have the C# code for this.
thanks.
Set Grid.Visibility on the grid when you push a button. You'll need an qualifying name x:Name="MyGrid" and could then set the visibility from code behind.
If you use some approach like MVVM, then you could databind the visibility of the grid to a bool in your ViewModel (and use a DataTrigger for this instead of the EventTrigger).
Edit:
As minimal as it can get:
<Grid x:Name="NotifyGrid" Visibility="Hidden">
<Label Content="Notification" />
</Grid>
<Button Content="Click" Click="Button_Click" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="50" />
And then in the Code Behind:
private void Button_Click(object sender, RoutedEventArgs e)
{
NotifyGrid.Visibility = System.Windows.Visibility.Visible;
}
I have a storyboard that animates an image's width. I created the animation with expression blend:
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(FrameworkElement.Width)"
Storyboard.TargetName="imageFoo">
<EasingDoubleKeyFrame KeyTime="0:0:0.9" Value="335">
<EasingDoubleKeyFrame.EasingFunction>
<BackEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
The problem is that I want to assign that storyboard to all the images in my application not just for the image imageFoo. I will like to start that animation when the MouseEnters an image. How can I do that?
You need to remove the Target name from the storyboard and also move the trigger into a style, there is no code behind required to do this thankfully
In your App.xaml file (or in any resources collection).
<Application.Resources>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)">
<EasingDoubleKeyFrame KeyTime="0:0:0.9" Value="335">
<EasingDoubleKeyFrame.EasingFunction>
<BackEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Application.Resources>
By declaring a style with no x:Key and simply giving a TargetType you're basically telling WPF that it's supposed to apply to every single element in the visual tree with that type.
I have been trying to animate the opening of a UserControl with no luck and was wondering if anyone could help?
I have a UserControl which simply holds information about a record. It opens up as a box on an existing page, however I would like the box to open with a simple animation. I'm trying to get the box to open with an expanding animation instead of the box just appearing.
Below is the code I have been working on.
<UserControl Name="RecordViewerUserControl"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
x:Class="VisionWare.MasterDataServices.Silverlight.UI.Common.RecordViewer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
xmlns:conv="clr-namespace:VisionWare.MasterDataServices.Silverlight.UI.Converters"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
Height="490"
Width="600"
Margin="0,0,0,0">
<UserControl.Resources>
<conv:DateConverter x:Key="dateConverter" />
<conv:BoolToVisibilityConverter x:Key="visibilityConverter" />
<conv:EntityIdToUrlConverter x:Key="urlConverter"/>
<conv:FileConverter x:Key="fileConverter"/>
<conv:AlertImageURLConverter x:Key="alertConverter"/>
<Style TargetType="UserControl" x:Key="CustomUserControlStyle">
<Setter Property="Effect">
<Setter.Value>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleX">
<SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="1.05" />
<SplineDoubleKeyFrame KeyTime="00:00:00.45" Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleY">
<SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="1.05" />
<SplineDoubleKeyFrame KeyTime="00:00:00.45" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
I have changed my code according to #jrb 's advice...]
<UserControl.Triggers>
<EventTrigger RoutedEvent="UserControl.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="RecordViewerUserControl" Storyboard.TargetProperty="Width" To="600"/>
<DoubleAnimation Storyboard.TargetName="RecordViewerUserControl" Storyboard.TargetProperty="Height" To="490"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</UserControl.Triggers>
I have inserted this just after the initial UserControl opening tag.
It is not complaining anymore when the app is run, however it doesn't seem to be having an effect.
Any ideas? Am I missing something in the code behind?
I think your animation values are wrong, in the end you should have a value of 1 (100% size) not 0.
Why do you animate on the first child of LayoutRoot? You should have RecordViewerUserControl as animation target instead.
I suggest you test setting the size on the usercontrol to 1 then use event trigger loaded (i think) and a simple doubleanimation to increase the size of the control.
<EventTrigger RoutedEvent="Loaded">
This is a working example, you can test it in kaxaml.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="1"
Height="1"
Background="Black">
<Page.Triggers>
<EventTrigger RoutedEvent="Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Width"
To="200"/>
<DoubleAnimation
Storyboard.TargetProperty="Height"
To="200"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Page.Triggers>
<Grid>
</Grid>
</Page>