I'm a bit a of XAML noob so this is probably something very simple I'm missing...
In a Windows Phone 8 app I have a map Pushpin I'm trying to animate with an effect very much like ripples in a pond. I have a large container eclipse and a child eclipse that will expand from 0 width/height to 30 width/height (the same size as the parent eclipse).
I'm doing this to visually indicate to the user that their location is actively being tracked, or just been picked up.
Unfortunately I've not managed to get my animation working.
<ControlTemplate x:Key="UserLocationPushpinControlTemplate" TargetType="m:Pushpin">
<Grid x:Name="ContentGrid" Width="34" Height="34">
<Grid.Resources>
<Storyboard x:Name="Storyboard1">
<DoubleAnimation
Storyboard.TargetName="Animated"
Storyboard.TargetProperty="Width"
From="0" To="30" Duration="0:0:1" AutoReverse="False"
RepeatBehavior="Forever" />
<DoubleAnimation
Storyboard.TargetName="Animated"
Storyboard.TargetProperty="Height"
From="0" To="30" Duration="0:0:1" AutoReverse="False"
RepeatBehavior="Forever" />
</Storyboard>
</Grid.Resources>
<Grid MinHeight="30" MinWidth="30">
<Ellipse x:Name="Parent" Margin="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="30"
Height="30"
Stroke="White"
StrokeThickness="3"
Fill="{StaticResource PrimaryColorBrush}"/>
<Ellipse x:Name="Animated" Margin="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="0"
Height="0"
Stroke="White"
StrokeThickness="2"/>
</Grid>
</Grid>
</ControlTemplate>
Just in case it's relevant - this ControlTemplate is within a UserControl housing my Windows Phone 7 / Bing map control (the Windows Phone 8 map control is lacking some functionality I require).
Any help would be greatly appreciated. Thank you.
Update
I can add an animation, but am not sure how to apply the Storyboard via code. Ideally I'd like to apply the Storyboard by code as I'd like to define a couple for different circumstances.
Here's the updated XAML:
<ControlTemplate x:Key="UserLocationPushpinControlTemplate" TargetType="m:Pushpin">
<Grid x:Name="ContentGrid" Width="34" Height="34">
<Grid.Resources>
<Storyboard x:Name="LocateStoryboard">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="AnimatedEllipse" RepeatBehavior="Forever">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="30"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="AnimatedEllipse" RepeatBehavior="Forever">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="30"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<Grid MinHeight="30" MinWidth="30">
<Ellipse x:Name="ParentEllipse" Margin="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="30"
Height="30"
Stroke="White"
StrokeThickness="3"
Fill="{StaticResource PrimaryColorBrush}"/>
<Ellipse x:Name="AnimatedEllipse" Margin="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="0"
Height="0"
Stroke="White"
StrokeThickness="2"/>
</Grid>
</Grid>
</ControlTemplate>
As a side note: I had issues creating the animation before as I was unaware that Blend does not record changes if you're tweaking the XAML code directly. You need to seek out the various property controls and set everything there.
This is the code I was trying to use to start the animation:
Pushpin pushpin = new Pushpin();
pushpin.Tag = PIN_TAG;
pushpin.Location = ViewModel.Location;
pushpin.Template = (ControlTemplate)Resources["UserLocationPushpinControlTemplate"];
pushpin.PositionOrigin = PositionOrigin.Center;
MapBase.Children.Add(pushpin);
Storyboard animation = (Storyboard)pushpin.Resources["LocateStoryboard"];
animation.Begin();
The storyboard variable is null. It seems I need to delve in to the ControlTemplate structure to dig down to the "LocateStoryboard" resource. Any ideas how to do this?
Not sure if it can help, but take a look at the article by Igor Ralic here... He has a detailed example on how to add a fade in animation on pushpins.
Related
I want to be able to translate a grid to the bottom of page when a button is clicked. Currently I am using TranslateTransform to achieve that but the problem is that I have to give an integer value to which I have to translate the grid which would change when the height of container changes. My Storyboard:
<Storyboard x:Name="LowerChamberSlideDown">
<DoubleAnimation Storyboard.TargetName="HeaderTrans"
BeginTime="0:0:1"
Storyboard.TargetProperty="Y"
To="288"
Duration="0:0:2"/>
</Storyboard>
My Grid:
<Grid x:Name="LowerChamberHeader"
Grid.Row="0"
VerticalAlignment="Top">
<Grid.RenderTransform>
<TranslateTransform x:Name="HeaderTrans" Y="0"></TranslateTransform>
</Grid.RenderTransform>
<TextBlock Text="Lower Chamber"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="15,0,0,0"
Foreground="White"/>
<Button Height="20"
HorizontalAlignment="Right"
Margin="0,0,10,0">
<Button.Background>
<ImageBrush ImageSource="Assets/bmpExpandCollapse.bmp"
Stretch="Uniform"/>
</Button.Background>
</Button>
<Grid.Background>
<ImageBrush ImageSource="Assets/bmpBlueImage.bmp"/>
</Grid.Background>
</Grid>
Is there a way to use VerticalAlignment property in animation and set it to bottom to translate the grid?
Got this answer from following link:
How to animate Margin property in WPF
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="GroupTileSecond"
Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<HorizontalAlignment>Center</HorizontalAlignment>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
Thanks,
Jessie
I couldn't find a solution that also shows the nice transition of grid to the bottom of screen so I solved this issue by determining the height of the screen on OnSizeChanged event and then recalculating the LowerChamberSlideDown.To property from code behind.
I added a ProgressBar to my application and I wanted it to have a transparent background, so I did it like this:
<ProgressBar IsIndeterminate="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<ProgressBar.Background>
<SolidColorBrush Color="Black" Opacity="0.5" />
</ProgressBar.Background>
</ProgressBar>
And in the Preview Window everything looks fine, however, when I run my app, the Background is simply not there. The solution I found to this is to put the ProgressBar in a Grid and set the Background property in the Grid, but since the Preview shows it right, and the property is there, shouldn't it work?
UPDATE:
Based on #Chris W. suggestion, I tried to override the default style of the ProgressBar element, like so:
<ProgressBar IsIndeterminate="True" Background="#FF000000" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="50">
<ProgressBar.Style>
<Style TargetType="ProgressBar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Indeterminate">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="DeterminateRoot"
Storyboard.TargetProperty="Opacity"
To="0.5"
Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ProgressBar.Style>
</ProgressBar>
But still, no juice.
Need to get rid of two (2) StoryBoard Animations
Document Outline > Right Click Progress Bar > Edit Template -> Edit A Copy
<!--
<FadeOutThemeAnimation Storyboard.TargetName="DeterminateRoot"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DeterminateRoot"/>
-->
And as #ricochete suggested if using Opacity = 1 change up the Z-Order of DeterminateRoot to be on top of the EllipseGrid
<Border x:Name="DeterminateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" MinHeight="{TemplateBinding MinHeight}">
<Rectangle x:Name="ProgressBarIndicator" Fill="{TemplateBinding Foreground}" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}"/>
</Border>
<Grid x:Name="EllipseGrid" Opacity="0">
<!-- ... more XAML Style -->
<Grid Background="#FFFF0000">
<ProgressBar IsIndeterminate="True" Style="{StaticResource ProgressBarStyle1}" Height="50" >
<ProgressBar.Background>
<SolidColorBrush Color="Black" Opacity="0.5"/>
</ProgressBar.Background>
</ProgressBar>
</Grid>
If you go look at the default template you'll see at the bottom of the template the Background only has a TemplateBinding in one spot for x:Name="DeterminateRoot" so that's the only place you'd see your color set from the Background property.
Then if you climb up through the Storyboard for the Indeterminate State you'll find;
<DoubleAnimation Storyboard.TargetName="DeterminateRoot"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0" />
...and you've got your ProgressBar set to IsIndeterminate="True" so you're setting the one place that accepts the Background property to a zero opacity explicitly.
So you could go pull that animation out of the Storyboard for that state, or put in your own new object to set your thing, or just do the workaround you mentioned by just throwing it in a Border or a Grid or something and doing it that way amongst other possibilities.
You might also try (once you've fixed your opacity setting issue from the storyboard) just flipping your SolidColorBrush with Opacity into just pure hex with the Alpha Channel set as 50% opacity equivalent. Making it just;
<ProgressBar Background="#80000000" IsIndeterminate="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
Anyhow, hope this helps, Cheers!
Currently working with Windows 8.1 and XAML Transitions.
I have a grid that translates across my page. Inside the grid I have an image which I want to scale.
When I set up the animations using Blend all is well but once deployed the scale animation on the image is never acted upon, it's as if the grid stops forces its children to ignore their transitions.
The same XAML code works as expected on Windows Phone, but not on Windows 8.1.
Here's some example code to illustrate:
<Page.Resources>
<ResourceDictionary>
<Storyboard x:Name="MainStoryboard">
<DoubleAnimationUsingKeyFrames x:Name="PanelOut" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="Panel1">
<EasingDoubleKeyFrame x:Name="PanelOutInitial" KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame x:Name="PanelOutKeyFrame" KeyTime="0:0:3" Value="-648">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames x:Name="PanelIn" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="Panel2">
<EasingDoubleKeyFrame x:Name="PanelInInitial" KeyTime="0" Value="648"/>
<EasingDoubleKeyFrame x:Name="PanelInKeyFrame" KeyTime="0:0:3" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="Image2">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="2"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="Image2">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="2"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ResourceDictionary>
</Page.Resources>
<Grid x:Name="LayoutRoot" Tapped="LayoutRoot_Tapped" Background="DarkGray">
<Grid
x:Name="Panel1"
Background="{StaticResource StoryBackgroundBrush}"
RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<CompositeTransform/>
</Grid.RenderTransform>
<Grid.CacheMode>
<BitmapCache></BitmapCache>
</Grid.CacheMode>
<Grid>
<Image x:Name="Image1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="/uicontent/images/AttractLoop/imaging3.jpg" Stretch="UniformToFill" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<CompositeTransform/>
</Image.RenderTransform>
</Image>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="Share photos easily." VerticalAlignment="Top" Margin="48,48,0,0" FontSize="68" FontFamily="Segoe UI" Foreground="#FFDA3B01"/>
</Grid>
</Grid>
<Grid
x:Name="Panel2"
Background="{StaticResource OneDriveBackgroundBrush}"
RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<CompositeTransform x:Name="Trans" TranslateY="800"/>
</Grid.RenderTransform>
<Grid.CacheMode>
<BitmapCache></BitmapCache>
</Grid.CacheMode>
<Grid>
<Image x:Name="Image2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="/uicontent/images/AttractLoop/imaging1.jpg" Stretch="UniformToFill">
<Image.RenderTransform>
<CompositeTransform/>
</Image.RenderTransform>
</Image>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="Tap to begin." VerticalAlignment="Top" Margin="48,48,0,0" FontSize="68" FontFamily="Segoe UI" Foreground="#FFDA3B01"/>
</Grid>
</Grid>
</Grid>
Interestingly, when I try to edit the transition in Blend the scale animation slider always snaps back to 0 as if there is a bug.
Any ideas as to why this is happening?
XAML for WinRT may be very similar to Silverlight, but since Windows Store applications can run in low-end devices, some restrictions have been introduced. In your case, you are trying to animate a child object, and that is considered a dependent animation. By default, WinRT doesn't execute dependent animations, unless you specify EnableDependentAnimation="True" when declaring the animation object.
I have an question about Expression Blend 4.
I want to create a simple component appearing animation, when height of component changes from 0 to 100% and components below it are moving down to allocate required space.
My problem is that only static values in pixels allowed to create such type of animation. But I did not know height of my control (actually, it is textBox in which content and content length may vary), and I cannot set Height value of last keyframe to Auto.
What should I do to implement this task?
Thanks in advance.
I guess the easist way would be using the Fluid Layout.
In the below example I created a TextBlock and set its Visibility to Collpased. Then when the Show visual state is triggered, I set its Visibility to Visible. Normally you can't animate the Visibility but if you enable the Fluid Layout behavior (also remember to define a TransitionEffect), it will animate it for you automatically.
<UserControl
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:ei="http://schemas.microsoft.com/expression/2010/interactions" xmlns:ee="http://schemas.microsoft.com/expression/2010/effects" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" mc:Ignorable="d"
x:Class="transformanimation.MainPage"
Width="640" Height="480">
<UserControl.Resources>
<Storyboard x:Name="Storyboard1">
<DoubleAnimation Duration="0:0:0.7" To="0.2" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="textBlock" d:IsOptimized="True"/>
<DoubleAnimation Duration="0:0:0.7" To="0.2" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="textBlock" d:IsOptimized="True"/>
</Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup" ei:ExtendedVisualStateManager.UseFluidLayout="True">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.2">
<ei:ExtendedVisualStateManager.TransitionEffect>
<ee:FadeTransitionEffect/>
</ei:ExtendedVisualStateManager.TransitionEffect>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Hide"/>
<VisualState x:Name="Show">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="textBlock">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<VisualStateManager.CustomVisualStateManager>
<ei:ExtendedVisualStateManager/>
</VisualStateManager.CustomVisualStateManager>
<Grid Margin="205,96,275,150">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock x:Name="textBlock" TextWrapping="Wrap" Text="TextBlock" FontSize="26.667" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed">
<TextBlock.RenderTransform>
<CompositeTransform/>
</TextBlock.RenderTransform>
</TextBlock>
<Rectangle Fill="#FF767689" Stroke="Black" Grid.Row="1"/>
</Grid>
<Button Content="hide" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="63,19,0,0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:GoToStateAction StateName="Hide"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button Content="show" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="183,20,0,0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:GoToStateAction StateName="Show"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</UserControl>
Of course if you don't want to use this magicial animation you can try animating its ScaleY. Something like this,
<DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="textBlock" d:IsOptimized="True"/>
Hope this helps! :)
Well, as the title suggests:
I have a storyboard and I want it's animation to start without the intervention of code.
The reason for this requirement is that I am targeting Silverlight Embedded and I am too lazy right now to recompile my application as well. And, coming to think of it, it will be easier to change the animation only in the future.
Does XAML have a property to make the storyboard run as soon as the xaml loads?
You can use the Loaded event to start your storyboard
See MSDN for an example:
Storyboard (Silverlight)
Picked the example from MSDN:
<Canvas
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Rectangle
x:Name="MyAnimatedRectangle"
Width="100"
Height="100"
Fill="Blue">
<Rectangle.Triggers>
<!-- Animates the rectangle's opacity.
This is the important part, the EventTrigger which will start our animation -->
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MyAnimatedRectangle"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:5" AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
The object Rectangle has properties. In the Triggers property we defined an EventTrigger which will fire when this event will occur. We choose the Rectangle.Loaded event, which means it will fire when loaded ;).
We add a BeginStoryboard property to begin our storyboard, and add a Storyboard. This animation will use a DoubleAnimation on the Opacity property, which means that in a duration of 5 seconds, the opacity will gradually fade to zero, and back (AutoReverse property) and it will do this Forever (the RepeatBehaviour property).
<UserControl x:Class="SOSMVVM.AniM11"
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'
mc:Ignorable='d'
d:DesignWidth='640'
d:DesignHeight='480'>
<StackPanel Margin="5">
<Rectangle Name="rect3" Fill="Blue" Margin="2" Width="20"
Height="20" HorizontalAlignment="Left" />
<Button Margin="2,20,0,0" HorizontalAlignment="Left"
Content="Start Animations" Width="100">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="rect3" Storyboard.TargetProperty="Width"
From="20" To="400" Duration="0:0:10" SpeedRatio="0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
</StackPanel>
</UserControl>