In my example app, I have a inner grid's height binded to the main grid's height. When I maximise and minimise the window, their heights are the same. after I execute an animation that changes the inner grid's height from 100 to binding the main grid's height again, the binding is lost. This is evident because when I maximise the window, the inner grids height remains the same while the main grid's height changes to fit the fill height of the window
Why is this and how can I fix it so the inner grid retains the main grid's height after I've set it back to that after an animation.
Example app:
<Window.Resources>
<Storyboard x:Key="ShrinkSlider" x:Name="ShrinkSlider"
Completed="ShrinkSlider_Completed">
<DoubleAnimation
Storyboard.TargetProperty="Height"
Storyboard.TargetName="gridSlider"
DecelerationRatio="0.9"
From="100"
To="{Binding ActualHeight, ElementName=gridMain}"
Duration="00:00:00.5" />
</Storyboard>
<Storyboard x:Key="ExpandSlider" x:Name="ExpandSlider"
Completed="ExpandSlider_Completed">
<DoubleAnimation
Storyboard.TargetProperty="Height"
Storyboard.TargetName="gridSlider"
DecelerationRatio="0.9"
From="{Binding ActualHeight, ElementName=gridMain}"
To="100"
Duration="00:00:00.5" />
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="ButtonBase.Click"
SourceName="btnShrink">
<BeginStoryboard x:Name="bsbShrinkSlider"
Storyboard="{StaticResource ShrinkSlider}" />
</EventTrigger>
<EventTrigger RoutedEvent="ButtonBase.Click"
SourceName="btnExpand">
<BeginStoryboard x:Name="bsbExpandSlider"
Storyboard="{StaticResource ExpandSlider}" />
</EventTrigger>
</Window.Triggers>
<Grid x:Name="gridMain">
<Grid x:Name="gridSlider"
Background="#1f1f1f"
VerticalAlignment="Top"
Height="{Binding ActualHeight, ElementName=gridMain}">
</Grid>
<StackPanel VerticalAlignment="Bottom">
<Button Content="Shrink"
x:Name="btnShrink"
Height="20"
Click="BtnShrink_Click" />
<Button Content="Expand"
x:Name="btnExpand"
Height="20"
Click="BtnExpand_Click" />
</StackPanel>
</Grid>
Okay so I figured it out. I needed to set Storyboard FillBehaviour = "Stop"
Then I needed to recreate the binding on the Storyboard Completed event:
Binding binding = new Binding();
binding.Source = gridMain;
binding.Path = new PropertyPath(Grid.ActualHeightProperty);
gridSlider.SetBinding(Grid.HeightProperty, binding);
Here is the full code amended:
xaml:
<Window.Resources>
<Storyboard x:Key="ShrinkSlider" x:Name="ShrinkSlider"
Completed="ShrinkSlider_Completed"
FillBehavior="Stop">
<DoubleAnimation
Storyboard.TargetProperty="Height"
Storyboard.TargetName="gridSlider"
DecelerationRatio="0.9"
From="{Binding ActualHeight, ElementName=gridMain}"
To="100"
Duration="00:00:00.5" />
</Storyboard>
<Storyboard x:Key="ExpandSlider" x:Name="ExpandSlider"
Completed="ExpandSlider_Completed"
FillBehavior="Stop">
<DoubleAnimation
Storyboard.TargetProperty="Height"
Storyboard.TargetName="gridSlider"
DecelerationRatio="0.9"
From="100"
To="{Binding ActualHeight, ElementName=gridMain}"
Duration="00:00:00.5" />
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="ButtonBase.Click"
SourceName="btnShrink">
<BeginStoryboard x:Name="bsbShrinkSlider"
Storyboard="{StaticResource ShrinkSlider}" />
</EventTrigger>
<EventTrigger RoutedEvent="ButtonBase.Click"
SourceName="btnExpand">
<BeginStoryboard x:Name="bsbExpandSlider"
Storyboard="{StaticResource ExpandSlider}" />
</EventTrigger>
</Window.Triggers>
<Grid x:Name="gridMain">
<Grid x:Name="gridSlider"
Background="#1f1f1f"
VerticalAlignment="Top"
Height="{Binding ActualHeight, ElementName=gridMain}">
</Grid>
<StackPanel VerticalAlignment="Bottom">
<Button Content="Shrink"
x:Name="btnShrink"
Height="20" />
<Button Content="Expand"
x:Name="btnExpand"
Height="20" />
</StackPanel>
</Grid>
cs:
private void ShrinkSlider_Completed(object sender, EventArgs e)
{
gridSlider.Height = 100;
}
private void ExpandSlider_Completed(object sender, EventArgs e)
{
Binding binding = new Binding();
binding.Source = gridMain;
binding.Path = new PropertyPath(Grid.ActualHeightProperty);
gridSlider.SetBinding(Grid.HeightProperty, binding);
}
Related
I'm new to WPF storyboard. I want to animate grid background color. I'm getting this error:
System.InvalidOperationException: 'Cannot resolve all property
references in the property path 'Background.Color'. Verify that
applicable objects support the properties.'
My XAML code:
<Grid x:Name="alert_grid">
<Grid.Resources>
<Storyboard x:Key="flashing_storyboard" Storyboard.TargetName="alert_grid">
<ColorAnimation
Storyboard.TargetProperty="Background.Color"
From="Black" To="Orange" Duration="0:0:2"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</Grid.Resources>
</Grid>
Code behind:
Storyboard sb = alert_grid.FindResource("flashing_storyboard") as Storyboard;
if (sb != null)
{
sb.Begin();
}
Any idea how to get the background color animated?
Please try this.
<Grid Name="alert_grid" Height="75" HorizontalAlignment="Left" Margin="27,12,0,0" VerticalAlignment="Top" Width="160" Background="LightGray">
<Grid.Triggers>
<EventTrigger RoutedEvent="Button.MouseLeave">
<BeginStoryboard>
<Storyboard x:Name ="flashing_storyboard" Storyboard.Target="{Binding ElementName=alert_grid}">
<ColorAnimation To="Orange" Storyboard.TargetProperty="(Grid.Background).(SolidColorBrush.Color)" From="Black"
AutoReverse="True" RepeatBehavior="Forever" FillBehavior="Stop" Duration="0:0:2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
</Grid>
and code behind
Storyboard sb = alert_grid.FindName("flashing_storyboard") as Storyboard;
if (sb != null)
{
sb.Begin();
}
As the title says, I want to know how to assign the height(or ActualHeight) of the container to the To parameter/attribute of DoubleAnimation in xaml?
Here is my code:
<Canvas Name="animCanvas">
<Rectangle
Name="animSquare"
Canvas.Left="0"
Fill="AliceBlue"
Stroke="Bisque"
StrokeThickness="5"
Width="100"
Height="100"
>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation
Storyboard.TargetName="animSquare"
Storyboard.TargetProperty="(Canvas.Top)"
From="0"
To="500" <!-- I want to set it to the containers height -->
Duration="0:0:1"
/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
You can apply Binding to the To property of double animation like this :
To="{Binding ElementName=animSquare, Path=Height}"
I think this would solve your issue.
Issue
The issue I am having is when a user clicks a button I want the button to start flashing from 100% visible to around 20% visible and the background of the WPF window to change colors from #ffffff to #d6786a and this should happen untill the button is clicked again. Then the animations should stop.
Code
I have done a bit of diging around to find where somone has done this and I can't seem to see anything. The code i have at the moment is as follows.
Here is the button I want to flash from 100% visible to 20% visible when clicked:
<Button Name="button2" Style="{DynamicResource NoChromeButton}" Visibility="{Binding VisableState, Converter={StaticResource BoolToVis}}" ToolTip="Start Live Stream" Command="{Binding PlayStream}" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="5" Height="22" Width="22" >
<Image Source="../Images/recordicon.png"/>
</Button>
I have tried to add a storyboard into the button and it just didn't work:
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard BeginTime="00:00:00"
RepeatBehavior="Forever"
Storyboard.TargetName="button2"
Storyboard.TargetProperty="(Visibility)">
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
I am new to WPF so going into animation is more difficult for me. If anyone could give me a little help on this stage it would be great.
Define animations in resources for example like this
<Window x:Name="window" x:Class="WpfApplication1.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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Storyboard x:Key="FlashButton" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="button">
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.2"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="ChangeColor">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid">
<EasingColorKeyFrame KeyTime="0:0:1" Value="Red"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="ChangeColor2">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid">
<EasingColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Grid x:Name="grid" Background="White">
<Button x:Name="button" Content="Button" Margin="10,10,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="75" Click="button_Click"/>
</Grid>
and create handler for button click
private bool isRunning;
private void button_Click(object sender, RoutedEventArgs e)
{
var flashButton = FindResource("FlashButton") as Storyboard;
var changeColor = FindResource("ChangeColor") as Storyboard;
var changeColor2 = FindResource("ChangeColor2") as Storyboard;
if (isRunning)
{
flashButton.Stop();
changeColor2.Begin();
isRunning = false;
}
else
{
flashButton.Begin();
changeColor.Begin();
isRunning = true;
}
}
To change "visibility to around 20%" you have to animate Opacity property (double type from 0.0 to 1.0) not Visibility (enum with 3 values, see msdn).
The goal can be easily achieved if you can use ToggleButton (because of its nice Checked and Unckecked routed events):
<ToggleButton>
<ToggleButton.Triggers>
<EventTrigger RoutedEvent="ToggleButton.Checked">
<BeginStoryboard x:Name="storyboard">
<Storyboard RepeatBehavior="Forever"
AutoReverse="True">
<DoubleAnimation Storyboard.TargetProperty="Opacity"
To="0.2"
Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="ToggleButton.Unchecked">
<StopStoryboard BeginStoryboardName="storyboard" />
</EventTrigger>
</ToggleButton.Triggers>
</ToggleButton>
I have set of images which are placed in pivot control.i want zoom in the image to a specific point and then go back to its normal size through animation.how can i do that.Any help will be appreciated.
<StackPanel>
<StackPanel.Resources>
<Storyboard x:Name="story">
<DoubleAnimation Storyboard.TargetName="img"
Storyboard.TargetProperty="Height"
From="300"
To="600"
Duration="0:0:2">
</DoubleAnimation>
</Storyboard>
</StackPanel.Resources>
<Button Height="100" Width="100" Click="Button_Click"></Button>
<Image x:Name="img" Height="300" Width="200" Source="/Assets/10.png"></Image>
</StackPanel>
first tip:-
avoid writing Resources into specific control. Instead define all resources into <Page.Resources>
Now, if you want to animate some control, then you have to use Scaling property of an element.
Check below code. here, I'm pointing out how to zoom the image on any event handler.
XAML code of control
<Image x:Name="img" Source="/Assets/image1.png" RenderTransformOrigin="0.5 0.5" >
<Image.RenderTransform>
<CompositeTransform x:Name="compositeTransform" />
</Image.RenderTransform>
</Image>
Defining Storyborad
<phone:PhoneApplicationPage.Resources>
<Storyboard x:Name="story">
<DoubleAnimation Storyboard.TargetName="compositeTransform"
Storyboard.TargetProperty="ScaleX"
From="0" To="5"
Duration="0:0:2" />
<DoubleAnimation Storyboard.TargetName="compositeTransform"
Storyboard.TargetProperty="ScaleY"
From="0" To="5"
Duration="0:0:2" />
</Storyboard>
</phone:PhoneApplicationPage.Resources>
On any of the event handler
story.Begin();
Hope that helps..
If I understand your problem, then you should use the Storyboard, EventTrigger and ScaleX Instead of Height for Resize image.
Storyboarded and trigger animations
Here is one option for the loaded event.
<StackPanel>
<Button Height="100" Width="100" Click="Button_Click"></Button>
<Image x:Name="img" Height="300" Width="200" Source="/Assets/10.png">
<Image.RenderTransform>
<ScaleTransform x:Name="ImageScale" ScaleX="1" ScaleY="1"/>
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ImageScale" Storyboard.TargetProperty="(ScaleTransform.ScaleX)" To="1.5" Duration="0:0:0.7" AutoReverse="True"/>
<DoubleAnimation Storyboard.TargetName="ImageScale" Storyboard.TargetProperty="(ScaleTransform.ScaleY)" To="1.5" Duration="0:0:0.7" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
</StackPanel>
I have a scrolling news ticker that is animated via a Storyboard. It currently works pretty well but I would like to pause it whenever the Mouse is over the TextBlock and then have it resume once the mouse is moved off of the TextBlock
<WrapPanel x:Name="Ticker" >
<TextBlock Text="{Binding NewsTicker, IsAsync=True}" FontSize="18" Foreground="White" >
<TextBlock.RenderTransform>
<TranslateTransform x:Name="translate" />
</TextBlock.RenderTransform>
<TextBlock.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard x:Name="NewsTicker">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation From="{Binding ElementName=Ticker, Path=ActualWidth}" To="{Binding ElementName=Ticker, Path=ActualWidth, Converter={StaticResource NegConverter}}" Storyboard.TargetName="translate" Storyboard.TargetProperty="X" Duration="0:0:35" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.EnterActions>
<PauseStoryboard BeginStoryboardName="NewsTicker" />
</EventTrigger.EnterActions>
<EventTrigger.ExitActions>
<ResumeStoryboard BeginStoryboardName="NewsTicker" />
</EventTrigger.ExitActions>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</WrapPanel>
I've tried several combinations of Pause and Resume Storyboard as well as different RoutedEvents. I even removed the EventTrigger.ExitAction just to see if the pause would work but it made no difference.
Instead of using EnterActions/ExitActions use MouseEnter and MouseLeave events
<TextBlock.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard x:Name="NewsTicker">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation ... />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseEnter">
<PauseStoryboard BeginStoryboardName="NewsTicker" />
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<ResumeStoryboard BeginStoryboardName="NewsTicker" />
</EventTrigger>
</TextBlock.Triggers>
since events don't have state there is no enter/exit action there is just action when event occurs
EventTrigger Class
Trigger objects have the Setters, EnterActions, and ExitActions properties that apply changes or actions based on the state of certain properties, while EventTrigger objects start a set of Actions when a specified routed event occurs