Im new in WPF, please if somebody can give me some tips to do this:
I need to move some images from to left or right, like in a coverflow (carousel, i can't use component as Dev Express, i have to do it for myself). And i need that if i maximize the window the "carousel" expand too and keep relation between margins of the images.
I try it moving the images in a Canvas, but when i maximize the window the Canvas dont do it and keep little.. I read and understand that i can't do that with a Canvas, so i do it putting the images on grids and changing its margin property, its works but when i maximize, the margin still is the same that when images are little and the aspect ratio is loose.
So my question is, how can i change the margin too when i maximize the window?
My code to move images using margin is:
<Storyboard Name="FlowIzq">
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Storyboard.TargetName="Image1" BeginTime="00:00:00">
<SplineThicknessKeyFrame KeyTime="00:00:00" Value="0,0,0,0"/>
<SplineThicknessKeyFrame KeyTime="00:00:0.5" Value="-157, 0,157,0"/>
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard.Storyboard>
I think i need to change the value of all SplineThicknessKeyFrame, but how i do that?
I hope explain it well and somebody can help me (sorry for my english) if something is not understood i explain it again.
Peace,
Rob.
4 years later I found myself needing a similar storyboard so I thought I'd share what I ended up with. Hopefully it helps someone else in 4 more years.
<Grid.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="1"
To="0"
Duration="0:0:1">
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="0"
To="1"
Duration="0:0:1"
BeginTime="0:0:1">
</DoubleAnimation>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Duration="00:00:1">
<SplineThicknessKeyFrame KeyTime="00:00:1" Value="0,0,500,0" />
</ThicknessAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Duration="00:00:1">
<DiscreteThicknessKeyFrame KeyTime="00:00:1.0" Value="0,0,-550,0" />
</ThicknessAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Duration="00:00:1" BeginTime="0:0:1">
<SplineThicknessKeyFrame KeyTime="00:00:1.0" Value="0" />
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
Just replace Grid.Triggers with your Control.Triggers and the EventTrigger.RoutedEvent to the event that makes sense to you.
Related
I have a textblock which should only show 2 lines of the text, while it is unselected. As soon as it gets selected, I want it to expand smoothly.
I started with something like:
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Second"
Storyboard.TargetProperty="(TextBlock.MaxHeight)"
To="50.0" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
But the issue here is, that I don't know how big the text is.
You should be able to use From='0' instead, which would start the animation with a value of 0 and end with whatever the value of MaxHeight is. However, that raises a different problem, as MaxHeight defaults to infinity, which would make the animation far too fast. Adding an ObjectAnimationUsingKeyframes at the start that sets MaxHeight to ActualHeight might work to resolve this. Something like this:
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyframes
Storyboard.TargetName='Second'
Storyboard.TargetProperty='(TextBlock.MaxHeight)'>
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding TargetName=Second, Path=ActualHeight}" />
</ObjectAnimationUsingKeyframes>
<DoubleAnimation
Storyboard.TargetName="Second"
Storyboard.TargetProperty="(TextBlock.MaxHeight)"
From="0" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
You can use DoubleAnimation to implement this. I have implemented this in a sample application.
<Window.Resources>
<Storyboard x:Key="OnGotFocus">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="textBox" Storyboard.TargetProperty="(FrameworkElement.Height)">
<EasingDoubleKeyFrame KeyTime="0:0:2">
<EasingDoubleKeyFrame.Value>
<System:Double>NaN</System:Double>
</EasingDoubleKeyFrame.Value>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnLostFocus">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="textBox" Storyboard.TargetProperty="(FrameworkElement.Height)">
<EasingDoubleKeyFrame KeyTime="0">
<EasingDoubleKeyFrame.Value>
<System:Double>NaN</System:Double>
</EasingDoubleKeyFrame.Value>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="30" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="UIElement.GotFocus" SourceName="textBox">
<BeginStoryboard Storyboard="{StaticResource OnGotFocus}" />
</EventTrigger>
<EventTrigger RoutedEvent="UIElement.LostFocus" SourceName="textBox">
<BeginStoryboard x:Name="OnLostFocus_BeginStoryboard" Storyboard="{StaticResource OnLostFocus}" />
</EventTrigger>
</Window.Triggers>
Your code for textbox should be :
<TextBox x:Name="textBox"
Height="30"
HorizontalAlignment="Right"
Text="Hello World" />
This will animate the textbox to a specified height as soon as it gets focussed. I have added an animation to collapse it as well when it loses focus.
Hope this helps you.
I'm using the following animation to "flash" a control:
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="1"
To="0.3"
AutoReverse="True"
Duration="0:0:0.5"
RepeatBehavior="Forever" />
The resulting effect is more like a fade in and out. What I'm really after is to just "flip" the opacity from one value to the other (and back) every 0.5 seconds, rather than a smooth transition. How do I achieve that?
This is the solution you are looking for:
<Storyboard RepeatBehavior="Forever" Duration="0:0:0.5" AutoReverse="True">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
<DiscreteDoubleKeyFrame Value="0.3" KeyTime="0:0:0.25" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
You can adapt it to your needs.
I would like to zoom in on a Image when Image.MouseEnter fires and then zoom out when Image.MouseLeave fires.
I thought of creating a Trigger, but no luck.
This is what i tried so far:
<Image Name="logo" Source="{Binding Path=ImagePath}"
Width="50" Height="50">
<Image.RenderTransform>
<ScaleTransform x:Name="TransRotate" />
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Image.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TransRotate"
Storyboard.TargetProperty="ScaleX"
From="0" To="100"
BeginTime="0:0:0"
Duration="0:0:10"
AutoReverse="False"/>
<DoubleAnimation Storyboard.TargetName="TransRotate"
Storyboard.TargetProperty="ScaleY"
From="0" To="100"
BeginTime="0:0:0"
Duration="0:0:10"
AutoReverse="False"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
Is this the correct way, or is there a better way?
I would remove the From property, this makes the animation jump, apart from that you just seem to be lacking the reverse animations on MouseLeave. Also to center the zoom you can set the RenderTransformOrigin of the Image to 0.5,0.5.
Instead of using those two events i usually prefer a trigger on IsMouseOver with Enter and ExitActions.
If you want to retain the space the image takes you can place it in a container with fixed size and set ClipToBounds to true.
I would like to do a sequence of animations on a label, for example, first do opacity animations from values 0 to 1 and vice versa and just at the end of opacity animation and not before a foreground animation. I would like to do it in XAML code and then start and finish de animation from C# code. Which is the best and efficient way to do it?
All replies are welcome!
Thanks in advance.
The easiest way is to define the entire animation in a single storyboard with suitable BeginTime and Duration properties. This way the entire animation can be started and stopped as a unit, but you can have different sequences.
For example:
<Storyboard Duration="0:00:06">
<DoubleAnimation Duration="0:0:4" Storyboard.TargetName="gear1RotateTransform" Storyboard.TargetProperty="Angle" From="-600" To="0"/>
<DoubleAnimation Duration="0:0:4" Storyboard.TargetName="gear2RotateTransform" Storyboard.TargetProperty="Angle" From="600" To="0"/>
<DoubleAnimation Duration="0:0:4" Storyboard.TargetName="gear3RotateTransform" Storyboard.TargetProperty="Angle" From="-600" To="0"/>
<DoubleAnimation BeginTime="0:0:1" Duration="0:00:02" Storyboard.TargetName="firstLetter" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0"/>
<DoubleAnimation BeginTime="0:0:2" Duration="0:00:02" Storyboard.TargetName="secondLetter" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0"/>
<DoubleAnimation BeginTime="0:0:3" Duration="0:00:02" Storyboard.TargetName="thirdLetter" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0"/>
<DoubleAnimation BeginTime="0:0:4" Duration="0:00:02" Storyboard.TargetName="siteLink" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0"/>
<DoubleAnimation BeginTime="0:0:4" Duration="0:00:02" Storyboard.TargetName="siteLinkTop" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0"/>
</Storyboard>
This storyboard changes the values on the 3 rotate transforms for the first 4 seconds, but the opacity on the firstLetter item doesn't start to change until after one second has passed and it only runs for 2 seconds. The siteLink and siteLinkTop elements don't have their opacity changed until after 4 seconds (and the gear rotation animation has finished).
In my current application I have this little animation. It makes a full 360 degrees rotation of a canvas and works fine.
<DoubleAnimation
Storyboard.TargetName="WaitCanvas"
Storyboard.TargetProperty="(Canvas.RenderTransform).(TransformGroup.Children)[0]
.(RotateTransform.Angle)"
From="0" To="360" Duration="0:0:2"
AutoReverse="False" RepeatBehavior="Forever" />
But the thing I want to do is not a smooth animation but animation is steps of 22.5 degrees each. How can this be done?
You could use a DoubleAnimationUsingKeyFrames and make two keyframes for each increment of 22.5 degrees at the same point in time.
Adding the XAML example which I was actually searching for.
<Storyboard
BeginTime="00:00:00"
RepeatBehavior="Forever"
Storyboard.TargetName="WaitCanvas"
Storyboard.TargetProperty="(Canvas.RenderTransform).(TransformGroup.Children)[0].(RotateTransform.Angle)">
<DoubleAnimationUsingKeyFrames Duration="0:0:2">
<DoubleKeyFrameCollection>
<DiscreteDoubleKeyFrame KeyTime="0:0:0.000" Value="0" />
<DiscreteDoubleKeyFrame KeyTime="0:0:0.125" Value="22.5" />
<DiscreteDoubleKeyFrame KeyTime="0:0:0.250" Value="45" />
<DiscreteDoubleKeyFrame KeyTime="0:0:0.375" Value="67.5" />
<DiscreteDoubleKeyFrame KeyTime="0:0:0.500" Value="90" />
<DiscreteDoubleKeyFrame KeyTime="0:0:0.625" Value="110.5" />
<!-- ... -->
</DoubleKeyFrameCollection>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
Even easier, use the DoubleAnimation "By" property, as in:
<DoubleAnimation
Storyboard.TargetName="WaitCanvas"
Storyboard.TargetProperty="(Canvas.RenderTransform).(TransformGroup.Children)[0]
.(RotateTransform.Angle)"
From="0" To="360" By="22.5" Duration="0:0:2"
AutoReverse="False" RepeatBehavior="Forever" />