I've worked with Opacity property in storyboard
but I cant figure it out how to move an UI element like grid stackpanel button ..... in c#?
(I am writing the storyboard in c# not in xaml )
Well, that depends on your actual layout: Do you want to animate a button in a Grid or in a Canvas (could animate the Margin property or the Canvas.Left attached property, respectively)? Do you want to animate the property itself or a transform (the latter would animate a RenderTransform - specifically a TranslateTransform). You would use the RenderTransform if you still want to refer to the "old" position.
One simple way is:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.Triggers>
<EventTrigger RoutedEvent="Grid.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="myButton"
Storyboard.TargetProperty="(Canvas.Left)" From="1" To="350"
Duration="0:0:10" BeginTime="0:0:0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Canvas x:Name="myCanvas" Background="Yellow">
<Button x:Name="myButton" Width="100" Height="30" Canvas.Left="100" Canvas.Top="100" />
</Canvas>
</Grid>
</Window>
it would be better if you use blend for storyboard ..i have genrated a code for stackpanel movement towards right ..just check it..
you can go through this video aslo it's very good it will perfectly work in your case
<Page.Resources>
<Storyboard x:Name="Storyboard1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="hello">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="100"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Name="hello" Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" >
<StackPanel.RenderTransform>
<CompositeTransform/>
</StackPanel.RenderTransform>
<TextBlock Text="hello1" FontSize="50" />
<Button Content="Button" FontSize="50" Click="Button_Click_1" />
</StackPanel>
</Grid>
and to start do this on button click..
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Storyboard1.Begin();
}
for better understand just read about how to use blend..
Related
There's a lot of questions around this on the net, but after reading them, and the MS docs on animation control, I'm unable to mimic storyboard control from XAML event triggers in C# code.
In this XAML file, I have a canvas that I am rotating. I'd like to add interactivity to the rotation,
<Window x:Class="GraphicsBook.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:k="clr-namespace:GraphicsBook;assembly=Testbed2D"
Title="2D Testbed"
KeyDown="KeyDownHandler"
Height="600"
Width="600" >
<DockPanel LastChildFill="True">
<StackPanel x:Name="stack" DockPanel.Dock ="Top" Orientation="Vertical" Background="#ECE9D8">
<Button Name="StartAnimationClick">Start animation</Button>
<Button Name="StopAnimationClick" Click="stopAnimationClick">Stop animation</Button>
<Canvas x:Name="Grid">
<Canvas.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="CanvasRotation" CenterX="300" CenterY="300" Angle="0"/>
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
<StackPanel.Triggers>
<EventTrigger RoutedEvent="Button.Click" SourceName="StartAnimationClick">
<BeginStoryboard Name="GridRotationStoryboard">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="CanvasRotation"
Storyboard.TargetProperty="Angle"
From="0.0" To="360.0"
Duration="00:00:10.00" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!--<EventTrigger RoutedEvent="Button.Click" SourceName="StopAnimationClick">
<StopStoryboard BeginStoryboardName="GridRotationStoryboard"/>
</EventTrigger>-->
</StackPanel.Triggers>
</StackPanel>
</DockPanel>
</Window>
The commented event trigger,
<!--<EventTrigger RoutedEvent="Button.Click" SourceName="StopAnimationClick">
<StopStoryboard BeginStoryboardName="GridRotationStoryboard"/>
</EventTrigger>-->
Does indeed work as expected, that is, if I click the button, the animation stops. However, the version of the XAML above tries to replicate this functionality in C#, but this doesn't work. The click handler looks like this,
private void stopAnimationClick(object sender, RoutedEventArgs e)
{
Debug.Print("Stop animation");
// ???
}
I'm unable to control the animation object in ???, not matter what technique I try to get a handle on it. I must be plumbing the pieces incorrectly somehow, but I can't see what is wrong.
You can mimic what the EventTrigger does by calling BeginAnimation with a second argument of null:
private void stopAnimationClick(object sender, RoutedEventArgs e)
{
CanvasRotation.BeginAnimation(RotateTransform.AngleProperty, null);
}
How to animate the text from bottom to top in UWP. Is there any better way to trigger style properties in UWP.
How to make text moving Animation from bottom to top in UWP
You could use DoubleAnimation to approach, Please refer the following code.
<Grid>
<Grid.Resources>
<Storyboard x:Name="MoveStoryboard">
<DoubleAnimation Storyboard.TargetName="Tbk"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
From="0" Windows10version1903:To="{x:Bind TbkY, Mode=TwoWay}" Duration="0:0:2">
</DoubleAnimation>
</Storyboard>
</Grid.Resources>
<TextBlock Loaded="Tbk_Loaded"
Name="Tbk"
Text="hello Nico"
VerticalAlignment="Bottom"
Visibility="Visible"
HorizontalAlignment="Center"
FontSize="22"
TextLineBounds="Full" >
<TextBlock.RenderTransform>
<CompositeTransform/>
</TextBlock.RenderTransform>
</TextBlock>
<Button Content="Move" Click="Button_Click"/>
</Grid>
Code Behind
private void Button_Click(object sender, RoutedEventArgs e)
{
MoveStoryboard.Begin();
}
public double TbkY { get; set; }
private void Tbk_Loaded(object sender, RoutedEventArgs e)
{
TbkY = -Tbk.ActualOffset.Y;
}
MVVM aproach to trigger story bord on datachange
We can also trigger the story board on Data change. I tried the below code its works for me. Use the below namespace before going to start . The nuget package will be availble on the link Microsoft.Xaml.Behaviors.Uwp.Managed
xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
xmlns:Media ="using:Microsoft.Xaml.Interactions.Media"
<Page.Resources>
<Storyboard x:Name="MoveStoryboard">
<DoubleAnimation Storyboard.TargetName="txttext1"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
From="0" To="-200" Duration="0:0:2">
</DoubleAnimation>
</Storyboard>
</Page.Resources>
<Grid>
<TextBlock Text="Sample text to Animate">
<interactivity:Interaction.Behaviors>
<core:DataTriggerBehavior Binding ={Binding AnimateText} Value = true>
<Media:ControlStoryboardAction Storyboard="{StaticResource MoveStoryboard}"/>
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<TextBlock.RenderTransform>
<CompositeTransform/>
</TextBlock.RenderTransform>
</TextBlock>
</Grid>
I have changed the AnimateText property in ViewModel. Whenever the property value is changed .The textblock will move bottom to top based on(- Y value that is To="-200").
I'am very new to this WinRT and XAML stuff and not sure how to achieve this goal. For my page layout I have basically 2 rows. The first row is representing my (static) basic menu with some buttons and pictures (about 130 height). The rest of the screen should be used to display content. Like this:
screen layout
now when a user clicks on a main menu button the submenu "filter settings" should be move down with an animation. The main content is also responding to this event and moving accordingly ("filter settings" should not overlay the main content).
My current idea to define this layout is using a grid with 3 rows and 2 frames placed inside it. When no filter is activated, I use rowspan for my main content to span over the whole area. When a click event is recognized, I change the rownum of the frame which hold the main content (ModuleContentFrame) to 2 and its rowspan to 1. Then I'am loading the filter page to frame ModuleFadeInFrame.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="130"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<Frame
x:Name="ModuleFadeInFrame"
Grid.Row="1"/>
<Frame
x:Name="ModuleContentFrame"
Grid.Row="1"
Grid.RowSpan="2"/>
</Grid>
My question is: is this layout definition with a grid and frames inside it a suitable solution to solve this problem and how can I achieve a "moving" animation when displaying a sub-menu. I tried this with an Storyboard but there the main content is just "jumping" to row 2
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ModuleContentFrame"
Storyboard.TargetProperty="(Grid.Row)">
<DiscreteObjectKeyFrame KeyTime="1" Value="2" />
</ObjectAnimationUsingKeyFrames>
You can't really animate Grid row/col/etc... changes. Also any animation that'll result in a layout change is a dependent animation - and has bad performance. What I'd do is something like this:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
x:Class="App1.MainPage"
mc:Ignorable="d">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MenuState">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.3">
<VisualTransition.GeneratedEasingFunction>
<ExponentialEase EasingMode="EaseInOut"/>
</VisualTransition.GeneratedEasingFunction>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="ClosedState"/>
<VisualState x:Name="OpenState">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="grid" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid Margin="0,50,0,0" Background="Black">
<TextBlock>
Long text blablabla
</TextBlock>
</Grid>
<Grid x:Name="grid" Margin="0,50,0,0" Height="50" VerticalAlignment="Top" Background="#77ffff00">
<Grid.RenderTransform>
<CompositeTransform TranslateY="-50"/>
</Grid.RenderTransform>
<Button Content="Close" >
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:GoToStateAction StateName="ClosedState"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
</Grid>
<Grid Margin="0,0,0,0" Height="50" VerticalAlignment="Top" Background="Red">
<Button Content="Open" >
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:GoToStateAction StateName="OpenState"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
</Grid>
</Grid>
</Grid>
</Page>
This way there's no layout change, as your submenu is going to end up on top of the content.
if you're really insisting on the 'not obscuring content' way
You could just have your submenu before your content with a Height="0", and animate the height of the element with a DoubleAnimation. If you do this, you'll have to set EnableDependentAnimation to true.
More info: https://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.media.animation.pointanimation.enabledependentanimation.aspx
Thank you Tamás, you helped me a lot getting my solution. I'am doing this now as follows:
This code goes into the edit:UserControl for each submenu. On the main page I then only have to handle my Button click events and call the appropriate Animation. Next Step is getting familiar with Blend as you suggested :-)
I marked your post as answer because it was the most helpful in finding my solution
<Grid x:Name="maingrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
<Grid.RenderTransform>
<CompositeTransform TranslateY="-360"/>
</Grid.RenderTransform>
<Grid.Resources>
<Storyboard x:Name="myStoryboardOpen">
<DoubleAnimation Duration="0:0:0.3" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="maingrid"
d:IsOptimized="True"/>
</Storyboard>
<Storyboard x:Name="myStoryboardClose">
<DoubleAnimation Duration="0:0:0.3" To="-360" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="maingrid"
d:IsOptimized="True"/>
</Storyboard>
</Grid.Resources>
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 can't come up with a solution for this problem in XAML:
I want to animate the width of the right button to a certain value when IsMouseOver of the left button is true. I dont know where to put this: in a style or template of one of the buttons or in a style on the grid. Is it even possible?
<Border Style="{StaticResource ContentBodyStyle}" x:Name="Border" >
<Grid Width="Auto" Height="Auto" Style="{DynamicResource GridStyle1}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Margin="0,0,0,0" Content="Button" Grid.Row="0" x:Name="BtnLeft" Style="{DynamicResource ButtonStyle1}"/>
<Button Margin="0,0,0,0" Content="Button" Grid.Column="1" x:Name="BtnRight" Width="0"/>
</Grid>
</Border>
Thanks
I am not sure you can set properties for controls outside of the scope of a control with a style assigned to it. Even if it is possible, it doesn't seem right to do so.
What you can do in your scenario is to use event triggers and storyboards, defined anywhere they'd be visible to both buttons. Here's an example of how to modify BtnLeft, although I'd prefer to put the storyboards a bit further up the tree to allow for reuse if necessary:
<Button Margin="0,0,0,0" Content="Button" Grid.Row="0" x:Name="BtnLeft" Style="{DynamicResource ButtonStyle1}">
<Button.Resources>
<Storyboard x:Key="OnMouseEnter1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="BtnRight"
Storyboard.TargetProperty="Width">
<SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="75"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnMouseLeave1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="BtnRight"
Storyboard.TargetProperty="Width">
<SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Button.Resources>
<Button.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter" SourceName="BtnLeft">
<BeginStoryboard Storyboard="{StaticResource OnMouseEnter1}"/>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave" SourceName="BtnLeft">
<BeginStoryboard Storyboard="{StaticResource OnMouseLeave1}"/>
</EventTrigger>
</Button.Triggers>
</Button>
Instead of the IsMouseOver property, you can use MouseEnter and MouseLeave events. That should give you the same functionality.
Edit: The SourceName property can be omitted from the EventTrigger when that trigger is defined within the scope of the button.