Button animation on view model property change? - wpf

I have the following xaml code. The XAML displays an animation on the button whenever the button is click. I want to start/stop the animation whenever a boolean property in the view model is changed. Any help is appreciated in advance.
<Button Name="button5" Width="100" Margin="10" HorizontalContentAlignment="Left">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="myBorder" Storyboard.TargetProperty="Width" From="0" To="94" Duration="0:0:1" AutoReverse="True" RepeatBehavior="5x" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
<Button.Content>
<Grid Width="94">
<Border HorizontalAlignment="Left" Width="0" Name="myBorder">
<Border.Background>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.115" Color="Black" />
<GradientStop Offset="0.715" Color="Red" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
</Border>
<TextBlock FontSize="14" HorizontalAlignment="Center">Search</TextBlock>
</Grid>
</Button.Content>
</Button>
Also how can i animate the button in such a way that once the border width has reached its max width a reverse animation should occur. I mean i want a wave like effect(using gradient) inside the button. The wave should turn back once it hits the rightmost end of the button. Same should repeat indefinitely. This animation will be controlled using a ViewModel boolean property.

Related

RenderTransform.TranslateTransform animating in usercontrol in wpf

i want to create a wpf usercontrol that displays an Image and has a toolbar panel,
i want to set features listed below to the my userControl:
tool bar panel hidden when mouse cursor is out side of the usercontrol.
When mouse cursor enter the usercontrol,toolbar panel move up from the bottom of the usercontrol and locate at the bottom of the usercontrol.
i create it but ,i have a problem ,
see bellow:
when mouse cursor enter the UserControl:
and when mouse cursor leaved UserControl:
My Problem:
when panel is moving out side of the UserControl,the out side parts must be invisible,
like bellow:
my UserControl's Xaml codes:
<UserControl.Resources>
<Storyboard x:Key="SB_MouseEnter">
<DoubleAnimation To="0" Storyboard.TargetName="button_panel" Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)" Duration="0:0:0.2"/>
</Storyboard>
<Storyboard x:Key="SB_MouseLeave">
<DoubleAnimation To="40" Storyboard.TargetName="button_panel" Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)" Duration="0:0:0.2"/>
</Storyboard>
</UserControl.Resources>
<UserControl.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<BeginStoryboard Storyboard="{StaticResource ResourceKey=SB_MouseEnter}"/>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<BeginStoryboard Storyboard="{StaticResource ResourceKey=SB_MouseLeave}"/>
</EventTrigger>
</UserControl.Triggers>
<Border CornerRadius="4" BorderBrush="SeaGreen" BorderThickness="2">
<Grid>
<Image Source="Images/Koala.jpg"/>
<StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" Name="button_panel" Height="40" RenderTransformOrigin="0.5,0.5">
<StackPanel.RenderTransform>
<TranslateTransform Y="40"/>
</StackPanel.RenderTransform>
<StackPanel.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="1"/>
<GradientStop Color="#66FFFFFF"/>
</LinearGradientBrush>
</StackPanel.Background>
<Button Padding="5" Margin="5,0" Width="80" Height="30">
Open
</Button>
<Button Padding="5" Margin="5,0" Width="80" Height="30">
Clear
</Button>
</StackPanel>
</Grid>
</Border>
Just Clip the button_panel when it leaves the Border with ClipToBounds="True" on the Border
something like:
...
<Border BorderBrush="SeaGreen"
BorderThickness="2"
ClipToBounds="True"
CornerRadius="4">
...
Now with ClipToBounds="True" being set on the Border, any child of the Border which is outside the Border is not going to be visible.
This would thus satisfy your requirement of having the StackPanel invisible when the mouse is not over the image as well since TranslateTransform keeps it outside the Border. Thus you only see the StackPanel when mouse is over the image and the Slide in/out is only visible inside the Border.

Need help to change the code for wpf animation

i am beginner in wpf. i got a code from a site for wpf animation. animation start when dock panel load. i want to change animation play time. i want when user click on Ellipse then animation start and when user click on dock panel then animation will stop.here is code.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DockPanel>
<Ellipse Width="200" Height="200" Name="MyEllipse">
<Ellipse.Fill>
<RadialGradientBrush >
<GradientStop Offset="0" Color="#CCCCCCCC" />
<GradientStop Offset="0.5" Color="white" />
<GradientStop Offset="1" Color="black"/>
</RadialGradientBrush >
</Ellipse.Fill>
</Ellipse>
<DockPanel.Triggers>
<EventTrigger RoutedEvent="Page.Loaded">
<BeginStoryboard Name="MyBeginStoryBoard">
<Storyboard Name="MyStoryBoard">
<DoubleAnimation Storyboard.TargetName="MyEllipse" Storyboard.TargetProperty="(Ellipse.Height)"
From="0" To="200" AutoReverse="true"
RepeatBehavior="0:0:10" BeginTime="0:0:0" />
<DoubleAnimation Storyboard.TargetName="MyEllipse" Storyboard.TargetProperty="(Ellipse.Width)"
From="0" To="200" AutoReverse="true"
RepeatBehavior="0:0:10" BeginTime="0:0:0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</DockPanel.Triggers>
</DockPanel>
</Grid>
Change the RoutedEvent to PreviewMouseDown instead of Page.Loaded.
EDIT :
You can stop the animation by adding this trigger to the DockPanel.Triggers:
<EventTrigger SourceName="MyEllipse" RoutedEvent="Ellipse.PreviewMouseDown">
<StopStoryboard BeginStoryboardName="MyBeginStoryBoard" />
</EventTrigger>
This will let you stop the animation by clicking on the Ellipse.
See MSDN for samples on pause/resume etc.

Animating an overlay color over a TextBlock

I'm trying to come up with a creative solution to give this particular effect:
My initial idea: A dynamically sized rectangle with a chroma key shader effect will slide into place over the text. However, I do not want to kill the fidelity of the text edges which tends to happen with shaders.
I also considered using the FormattedText class, though I'm not sure it supports what I'm trying to do.
Any suggestions?
EDIT
To clarify, the text will be essentially a 'TabItem'. I would like the highlighted block to float across all tab items to the selected item. They are currently laid out in a Canvas with logic handling their positioning. A simple animation would not suffice it would seem.
This should give you the effect you want. This uses a gradient brush for the color, but it uses 3 gradient stops to make sure that the color changes immediately from one to the next with no gradient in between.
<Window
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:TestingWPF"
mc:Ignorable="d"
x:Class="TestingWPF.TestWindow"
d:DesignWidth="477" d:DesignHeight="214"
Background="Black">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="74" FontWeight="Bold">
<TextBlock.Foreground>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="White" Offset="0"/>
<GradientStop x:Name="WhiteOffset" Color="White" Offset="1"/>
<GradientStop x:Name="GrayOffset" Color="Gray" Offset="1"/>
</LinearGradientBrush>
</TextBlock.Foreground>
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard Storyboard.TargetProperty="Offset" Duration="0:0:1" RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="WhiteOffset" From="0" To="1" />
<DoubleAnimation Storyboard.TargetName="GrayOffset" From="0" To="1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
Some Text
</TextBlock>
</Window>

Animate Text Glint On Animated Text

I have a button that loads more data into a datagrid when clicked. To indicate progress, I change the text of the button to change from "More" to "Loading..." where the periods are animated. Next, I wanted to add a "glint" effect so that the text catches your eye. If you've used an iPhone/iPod Touch, I'm thinking of the effect on the "Slide To Unlock" text of the lock screen.
To do so, I shift a middle, lighter gradient stop from left to right. Because the animation continuously loops, I used offsets outside of the valid range to create a delay between the times when the light gradient stop is actually visible.
I got this implemented but I can tell that for some reason, the light gradient is not starting at the left edge of the text. It starts at about the 'a' in the "Loading". I accepted that and it's been in place for a while, but I'm now coming back to it just to try to understand why. It seems like maybe it's using the measure of the original text when calculating the animation, but I thought the animations were supposed to apply to each other when in the same storyboard. Here is my code:
<UserControl.Resources>
<local:EmptyBatchNumConverter x:Key="emptyBatchNumConverter" />
<BeginStoryboard x:Key="bsbLoadingMore" x:Name="bsbLoadingMore">
<Storyboard x:Name="sbLoadingMore">
<StringAnimationUsingKeyFrames Storyboard.TargetName="txtBtnMoreText" Storyboard.TargetProperty="Text" Duration="0:0:2" FillBehavior="Stop" RepeatBehavior="Forever">
<DiscreteStringKeyFrame Value="Loading" KeyTime="0:0:0" />
<DiscreteStringKeyFrame Value="Loading." KeyTime="0:0:0.5" />
<DiscreteStringKeyFrame Value="Loading.." KeyTime="0:0:1" />
<DiscreteStringKeyFrame Value="Loading..." KeyTime="0:0:1.5" />
</StringAnimationUsingKeyFrames>
<!--Animate the OffSet of the light gradient stop for a "glint" effect. Using -4.5 to 4.5 to delay the visible effect between repeats (and
control the speed relative to the duration). Using an extra .4 seconds to offset the frequency from the text animation. -->
<DoubleAnimation Storyboard.TargetName="gs2" Storyboard.TargetProperty="Offset" From="-4.5" To="4.5" Duration="0:0:2.4" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</UserControl.Resources>
...
<Button Name="btnMore" Grid.Row="1" Style="{StaticResource OasisGridMoreButton}" Click="btnMore_Click" Visibility="Visible" Height="16">
<Button.Content>
<TextBlock Name="txtBtnMoreText" MinWidth="48" Text="More..." /> <!--MinWidth = width of "Loading..."-->
</Button.Content>
<Button.Foreground>
<LinearGradientBrush StartPoint="0.2,0" EndPoint="1,1">
<GradientStop x:Name="gs1" Color="Black" Offset="0"/>
<GradientStop x:Name="gs2" Color="Cyan" Offset="-4.5"/>
<GradientStop x:Name="gs3" Color="Black" Offset="1" />
</LinearGradientBrush>
</Button.Foreground>
</Button>
Here is the problem:
<LinearGradientBrush StartPoint="0.2,0" EndPoint="1,1">
Change it to:
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
Here is the full test app I made (slowed down glint to see it better):
<Window
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"
x:Class="WpfApplication4.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<Storyboard x:Key="OnLoaded1"/>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard x:Name="bsbLoadingMore">
<Storyboard x:Name="sbLoadingMore">
<StringAnimationUsingKeyFrames Storyboard.TargetName="txtBtnMoreText" Storyboard.TargetProperty="Text" Duration="0:0:2" FillBehavior="Stop" RepeatBehavior="Forever">
<DiscreteStringKeyFrame Value="Loading" KeyTime="0:0:0" />
<DiscreteStringKeyFrame Value="Loading." KeyTime="0:0:0.5" />
<DiscreteStringKeyFrame Value="Loading.." KeyTime="0:0:1" />
<DiscreteStringKeyFrame Value="Loading..." KeyTime="0:0:1.5" />
</StringAnimationUsingKeyFrames>
<!--Animate the OffSet of the light gradient stop for a "glint" effect. Using -4.5 to 4.5 to delay the visible effect between repeats (and
control the speed relative to the duration). Using an extra .4 seconds to offset the frequency from the text animation. -->
<DoubleAnimation Storyboard.TargetName="gs2" Storyboard.TargetProperty="Offset" From="-4.5" To="4.5" Duration="0:0:5.4" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="LayoutRoot">
<Button x:Name="btnMore" Visibility="Visible" Margin="0,213,0,182" d:LayoutOverrides="GridBox">
<Button.Foreground>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop x:Name="gs1" Color="Black" Offset="0"/>
<GradientStop x:Name="gs2" Color="Cyan" Offset="0"/>
<GradientStop x:Name="gs3" Color="Black" Offset="1" />
</LinearGradientBrush>
</Button.Foreground>
<TextBlock x:Name="txtBtnMoreText" MinWidth="48" Text="More..." />
</Button>
</Grid>
For some reason, it is not showing the </Window> at the end...

Creating button content with centered text and animated border

The following XAML code creates a button with a border as its content. The border has a TextBlock as it's child. When you CLICK on the button, the border width gradually grows.
Since the text block is inside the border it is not seen until you click the button.
Now my requirements are:
There should be a text displayed on the button even before you click it.
Even after you click the button, only the border should animate while the button text remains in its center position.
<Button Name="button5" Width="100" Margin="10" HorizontalContentAlignment="Left">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="myBorder" Storyboard.TargetProperty="Width" From="0" To="94" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
<Button.Content>
<Border Background="Gray" Width="0" Name="myBorder">
<TextBlock>Search</TextBlock>
</Border>
</Button.Content>
</Button>
I will appreciate if anyone is able to provide answers with working XAML code.
I've modified your XAML only slightly:
<Button Name="button5" Width="100" Margin="10" HorizontalContentAlignment="Left">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="myRectangle" Storyboard.TargetProperty="Width" From="0" To="94" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
<Button.Content>
<Grid>
<Rectangle x:Name="myRectangle" Fill="Gray" Width="0" HorizontalAlignment="Left" />
<TextBlock Text="Search" />
</Grid>
</Button.Content>
</Button>
For the Button's content, you could use a Grid which contains your Border and the TextBlock. Since no columns or rows are specified, the TextBlock and the Border are drawn on top of each other. It situations like this where the Border does not have content, I prefer to use a Rectangle instead since it is bit lighter. Hope this helps!

Resources